1 // Copyright 2015 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <chrono>
16 #include <cstdio>
17 #include <future>
18 #include <iomanip>
19 #include <iostream>
20 #include <memory>
21 #include <string>
22 #include <vector>
23 
24 #include <base/command_line.h>
25 #include <base/files/file_util.h>
26 #include <base/strings/string_number_conversions.h>
27 #include <base/strings/string_split.h>
28 #include <base/strings/string_util.h>
29 
30 #include <aidl/android/security/apc/BnConfirmationCallback.h>
31 #include <aidl/android/security/apc/IProtectedConfirmation.h>
32 #include <aidl/android/system/keystore2/IKeystoreService.h>
33 #include <aidl/android/system/keystore2/ResponseCode.h>
34 #include <android/binder_manager.h>
35 #include <android/binder_process.h>
36 #include <keymint_support/authorization_set.h>
37 
38 #include <openssl/evp.h>
39 #include <openssl/mem.h>
40 #include <openssl/x509.h>
41 
42 #include "keystore_client.pb.h"
43 
44 namespace apc = ::aidl::android::security::apc;
45 namespace keymint = ::aidl::android::hardware::security::keymint;
46 namespace ks2 = ::aidl::android::system::keystore2;
47 
48 using base::CommandLine;
49 using keystore::EncryptedData;
50 
51 namespace {
52 
53 struct TestCase {
54     std::string name;
55     bool required_for_brillo_pts;
56     keymint::AuthorizationSet parameters;
57 };
58 
59 constexpr const char keystore2_service_name[] = "android.system.keystore2.IKeystoreService/default";
60 
unwrapError(const ndk::ScopedAStatus & status)61 int unwrapError(const ndk::ScopedAStatus& status) {
62     if (status.isOk()) return 0;
63     if (status.getExceptionCode() == EX_SERVICE_SPECIFIC) {
64         return status.getServiceSpecificError();
65     } else {
66         return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
67     }
68 }
69 
keyDescriptor(const std::string & alias)70 ks2::KeyDescriptor keyDescriptor(const std::string& alias) {
71     return {
72         .domain = ks2::Domain::APP,
73         .nspace = -1,  // ignored - should be -1.
74         .alias = alias,
75         .blob = {},
76     };
77 }
78 
PrintUsageAndExit()79 void PrintUsageAndExit() {
80     printf("Usage: keystore_client_v2 <command> [options]\n");
81     printf("Commands: brillo-platform-test [--prefix=<test_name_prefix>] [--test_for_0_3]\n"
82            "          list-brillo-tests\n"
83            "          add-entropy --input=<entropy> [--seclevel=software|strongbox|tee(default)]\n"
84            "          generate --name=<key_name> [--seclevel=software|strongbox|tee(default)]\n"
85            "          get-chars --name=<key_name>\n"
86            "          export --name=<key_name>\n"
87            "          delete --name=<key_name>\n"
88            "          delete-all\n"
89            "          exists --name=<key_name>\n"
90            "          list [--prefix=<key_name_prefix>]\n"
91            "          list-apps-with-keys\n"
92            "          sign-verify --name=<key_name>\n"
93            "          [en|de]crypt --name=<key_name> --in=<file> --out=<file>\n"
94            "                       [--seclevel=software|strongbox|tee(default)]\n"
95            "          confirmation --prompt_text=<PromptText> --extra_data=<hex>\n"
96            "                       --locale=<locale> [--ui_options=<list_of_ints>]\n"
97            "                       --cancel_after=<seconds>\n");
98     exit(1);
99 }
100 
CreateKeystoreInstance()101 std::shared_ptr<ks2::IKeystoreService> CreateKeystoreInstance() {
102     ::ndk::SpAIBinder keystoreBinder(AServiceManager_checkService(keystore2_service_name));
103     auto result = ks2::IKeystoreService::fromBinder(keystoreBinder);
104     if (result) return result;
105     std::cerr << "Unable to connect to Keystore.";
106     exit(-1);
107 }
108 
109 std::shared_ptr<ks2::IKeystoreSecurityLevel>
GetSecurityLevelInterface(std::shared_ptr<ks2::IKeystoreService> keystore,keymint::SecurityLevel securitylevel)110 GetSecurityLevelInterface(std::shared_ptr<ks2::IKeystoreService> keystore,
111                           keymint::SecurityLevel securitylevel) {
112     std::shared_ptr<ks2::IKeystoreSecurityLevel> sec_level;
113     auto rc = keystore->getSecurityLevel(securitylevel, &sec_level);
114     if (rc.isOk()) return sec_level;
115     std::cerr << "Unable to get security level interface from Keystore: " << rc.getDescription();
116     exit(-1);
117 }
118 
isHardwareEnforced(const ks2::Authorization & a)119 bool isHardwareEnforced(const ks2::Authorization& a) {
120     return !(a.securityLevel == keymint::SecurityLevel::SOFTWARE ||
121              a.securityLevel == keymint::SecurityLevel::KEYSTORE);
122 }
123 
PrintTags(const std::vector<ks2::Authorization> & characteristics,bool printHardwareEnforced)124 void PrintTags(const std::vector<ks2::Authorization>& characteristics, bool printHardwareEnforced) {
125     for (const auto& a : characteristics) {
126         if (isHardwareEnforced(a) == printHardwareEnforced) {
127             std::cout << toString(a.keyParameter.tag) << "\n";
128         }
129     }
130 }
131 
PrintKeyCharacteristics(const std::vector<ks2::Authorization> & characteristics)132 void PrintKeyCharacteristics(const std::vector<ks2::Authorization>& characteristics) {
133     printf("Hardware:\n");
134     PrintTags(characteristics, true /* printHardwareEnforced */);
135     printf("Software:\n");
136     PrintTags(characteristics, false /* printHardwareEnforced */);
137 }
138 
139 const char kEncryptSuffix[] = "_ENC";
140 const char kAuthenticateSuffix[] = "_AUTH";
141 constexpr uint32_t kAESKeySize = 256;      // bits
142 constexpr uint32_t kHMACKeySize = 256;     // bits
143 constexpr uint32_t kHMACOutputSize = 256;  // bits
144 
verifyEncryptionKeyAttributes(const std::vector<ks2::Authorization> authorizations)145 bool verifyEncryptionKeyAttributes(const std::vector<ks2::Authorization> authorizations) {
146     bool verified = true;
147     verified =
148         verified &&
149         std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
150             return a.keyParameter.tag == keymint::Tag::ALGORITHM &&
151                    a.keyParameter.value ==
152                        keymint::KeyParameterValue::make<keymint::KeyParameterValue::algorithm>(
153                            keymint::Algorithm::AES);
154         });
155 
156     verified =
157         verified &&
158         std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
159             return a.keyParameter.tag == keymint::Tag::KEY_SIZE &&
160                    a.keyParameter.value ==
161                        keymint::KeyParameterValue::make<keymint::KeyParameterValue::integer>(
162                            kAESKeySize);
163         });
164 
165     verified =
166         verified &&
167         std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
168             return a.keyParameter.tag == keymint::Tag::BLOCK_MODE &&
169                    a.keyParameter.value ==
170                        keymint::KeyParameterValue::make<keymint::KeyParameterValue::blockMode>(
171                            keymint::BlockMode::CBC);
172         });
173 
174     verified =
175         verified &&
176         std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
177             return a.keyParameter.tag == keymint::Tag::PADDING &&
178                    a.keyParameter.value ==
179                        keymint::KeyParameterValue::make<keymint::KeyParameterValue::paddingMode>(
180                            keymint::PaddingMode::PKCS7);
181         });
182 
183     return verified;
184 }
185 
verifyAuthenticationKeyAttributes(const std::vector<ks2::Authorization> authorizations)186 bool verifyAuthenticationKeyAttributes(const std::vector<ks2::Authorization> authorizations) {
187     bool verified = true;
188     verified =
189         verified &&
190         std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
191             return a.keyParameter.tag == keymint::Tag::ALGORITHM &&
192                    a.keyParameter.value ==
193                        keymint::KeyParameterValue::make<keymint::KeyParameterValue::algorithm>(
194                            keymint::Algorithm::HMAC);
195         });
196 
197     verified =
198         verified &&
199         std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
200             return a.keyParameter.tag == keymint::Tag::KEY_SIZE &&
201                    a.keyParameter.value ==
202                        keymint::KeyParameterValue::make<keymint::KeyParameterValue::integer>(
203                            kHMACKeySize);
204         });
205 
206     verified =
207         verified &&
208         std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
209             return a.keyParameter.tag == keymint::Tag::MIN_MAC_LENGTH &&
210                    a.keyParameter.value ==
211                        keymint::KeyParameterValue::make<keymint::KeyParameterValue::integer>(
212                            kHMACOutputSize);
213         });
214 
215     verified =
216         verified &&
217         std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
218             return a.keyParameter.tag == keymint::Tag::DIGEST &&
219                    a.keyParameter.value ==
220                        keymint::KeyParameterValue::make<keymint::KeyParameterValue::digest>(
221                            keymint::Digest::SHA_2_256);
222         });
223     return verified;
224 }
225 
226 std::variant<int, ks2::KeyEntryResponse>
loadOrCreateAndVerifyEncryptionKey(const std::string & name,keymint::SecurityLevel securityLevel,bool create)227 loadOrCreateAndVerifyEncryptionKey(const std::string& name, keymint::SecurityLevel securityLevel,
228                                    bool create) {
229     auto keystore = CreateKeystoreInstance();
230 
231     ks2::KeyEntryResponse keyEntryResponse;
232 
233     bool foundKey = true;
234     auto rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
235     if (!rc.isOk()) {
236         auto error = unwrapError(rc);
237         if (ks2::ResponseCode(error) == ks2::ResponseCode::KEY_NOT_FOUND && create) {
238             foundKey = false;
239         } else {
240             std::cerr << "Failed to get key entry: " << rc.getDescription() << std::endl;
241             return error;
242         }
243     }
244 
245     if (!foundKey) {
246         auto sec_level = GetSecurityLevelInterface(keystore, securityLevel);
247         auto params = keymint::AuthorizationSetBuilder()
248                           .AesEncryptionKey(kAESKeySize)
249                           .Padding(keymint::PaddingMode::PKCS7)
250                           .Authorization(keymint::TAG_BLOCK_MODE, keymint::BlockMode::CBC)
251                           .Authorization(keymint::TAG_NO_AUTH_REQUIRED);
252 
253         ks2::KeyMetadata keyMetadata;
254 
255         rc = sec_level->generateKey(keyDescriptor(name), {} /* attestationKey */,
256                                     params.vector_data(), 0 /* flags */, {} /* entropy */,
257                                     &keyMetadata);
258         if (!rc.isOk()) {
259             std::cerr << "Failed to generate key: " << rc.getDescription() << std::endl;
260             return unwrapError(rc);
261         }
262 
263         rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
264         if (!rc.isOk()) {
265             std::cerr << "Failed to get key entry (second try): " << rc.getDescription()
266                       << std::endl;
267             return unwrapError(rc);
268         }
269     }
270 
271     if (!verifyEncryptionKeyAttributes(keyEntryResponse.metadata.authorizations)) {
272         std::cerr << "Key has wrong set of parameters." << std::endl;
273         return static_cast<int>(ks2::ResponseCode::INVALID_ARGUMENT);
274     }
275 
276     return keyEntryResponse;
277 }
278 
279 std::variant<int, ks2::KeyEntryResponse>
loadOrCreateAndVerifyAuthenticationKey(const std::string & name,keymint::SecurityLevel securityLevel,bool create)280 loadOrCreateAndVerifyAuthenticationKey(const std::string& name,
281                                        keymint::SecurityLevel securityLevel, bool create) {
282     auto keystore = CreateKeystoreInstance();
283 
284     ks2::KeyEntryResponse keyEntryResponse;
285 
286     bool foundKey = true;
287     auto rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
288     if (!rc.isOk()) {
289         auto error = unwrapError(rc);
290         if (ks2::ResponseCode(error) == ks2::ResponseCode::KEY_NOT_FOUND && create) {
291             foundKey = false;
292         } else {
293             std::cerr << "Failed to get HMAC key entry: " << rc.getDescription() << std::endl;
294             return error;
295         }
296     }
297 
298     if (!foundKey) {
299         auto sec_level = GetSecurityLevelInterface(keystore, securityLevel);
300         auto params = keymint::AuthorizationSetBuilder()
301                           .HmacKey(kHMACKeySize)
302                           .Digest(keymint::Digest::SHA_2_256)
303                           .Authorization(keymint::TAG_MIN_MAC_LENGTH, kHMACOutputSize)
304                           .Authorization(keymint::TAG_NO_AUTH_REQUIRED);
305 
306         ks2::KeyMetadata keyMetadata;
307 
308         rc = sec_level->generateKey(keyDescriptor(name), {} /* attestationKey */,
309                                     params.vector_data(), 0 /* flags */, {} /* entropy */,
310                                     &keyMetadata);
311         if (!rc.isOk()) {
312             std::cerr << "Failed to generate HMAC key: " << rc.getDescription() << std::endl;
313             return unwrapError(rc);
314         }
315 
316         rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
317         if (!rc.isOk()) {
318             std::cerr << "Failed to get HMAC key entry (second try): " << rc.getDescription()
319                       << std::endl;
320             return unwrapError(rc);
321         }
322     }
323 
324     if (!verifyAuthenticationKeyAttributes(keyEntryResponse.metadata.authorizations)) {
325         std::cerr << "Key has wrong set of parameters." << std::endl;
326         return static_cast<int>(ks2::ResponseCode::INVALID_ARGUMENT);
327     }
328 
329     return keyEntryResponse;
330 }
331 
332 std::variant<int, std::vector<uint8_t>>
encryptWithAuthentication(const std::string & name,const std::vector<uint8_t> & data,keymint::SecurityLevel securityLevel)333 encryptWithAuthentication(const std::string& name, const std::vector<uint8_t>& data,
334                           keymint::SecurityLevel securityLevel) {
335     // The encryption algorithm is AES-256-CBC with PKCS #7 padding and a random
336     // IV. The authentication algorithm is HMAC-SHA256 and is computed over the
337     // cipher-text (i.e. Encrypt-then-MAC approach). This was chosen over AES-GCM
338     // because hardware support for GCM is not mandatory for all Brillo devices.
339     std::string encryption_key_name = name + kEncryptSuffix;
340     auto encryption_key_result =
341         loadOrCreateAndVerifyEncryptionKey(encryption_key_name, securityLevel, true /* create */);
342     if (auto error = std::get_if<int>(&encryption_key_result)) {
343         return *error;
344     }
345     auto encryption_key = std::get<ks2::KeyEntryResponse>(encryption_key_result);
346 
347     std::string authentication_key_name = name + kAuthenticateSuffix;
348     auto authentication_key_result = loadOrCreateAndVerifyAuthenticationKey(
349         authentication_key_name, securityLevel, true /* create */);
350     if (auto error = std::get_if<int>(&authentication_key_result)) {
351         return *error;
352     }
353     auto authentication_key = std::get<ks2::KeyEntryResponse>(authentication_key_result);
354 
355     ks2::CreateOperationResponse encOperationResponse;
356     auto encrypt_params = keymint::AuthorizationSetBuilder()
357                               .Authorization(keymint::TAG_PURPOSE, keymint::KeyPurpose::ENCRYPT)
358                               .Padding(keymint::PaddingMode::PKCS7)
359                               .Authorization(keymint::TAG_BLOCK_MODE, keymint::BlockMode::CBC);
360 
361     auto rc = encryption_key.iSecurityLevel->createOperation(
362         encryption_key.metadata.key, encrypt_params.vector_data(), false /* forced */,
363         &encOperationResponse);
364     if (!rc.isOk()) {
365         std::cerr << "Failed to begin encryption operation: " << rc.getDescription() << std::endl;
366         return unwrapError(rc);
367     }
368 
369     std::optional<std::vector<uint8_t>> optCiphertext;
370 
371     rc = encOperationResponse.iOperation->finish(data, {}, &optCiphertext);
372     if (!rc.isOk()) {
373         std::cerr << "Failed to finish encryption operation: " << rc.getDescription() << std::endl;
374         return unwrapError(rc);
375     }
376 
377     std::vector<uint8_t> initVector;
378     if (auto params = encOperationResponse.parameters) {
379         for (auto& p : params->keyParameter) {
380             if (auto iv = keymint::authorizationValue(keymint::TAG_NONCE, p)) {
381                 initVector = std::move(iv->get());
382                 break;
383             }
384         }
385         if (initVector.empty()) {
386             std::cerr << "Encryption operation did not return an IV." << std::endl;
387             return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
388         }
389     }
390 
391     if (!optCiphertext) {
392         std::cerr << "Encryption succeeded but no ciphertext returned." << std::endl;
393         return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
394     }
395 
396     auto ciphertext = std::move(*optCiphertext);
397     auto toBeSigned = initVector;
398     toBeSigned.insert(toBeSigned.end(), ciphertext.begin(), ciphertext.end());
399 
400     ks2::CreateOperationResponse signOperationResponse;
401     auto sign_params = keymint::AuthorizationSetBuilder()
402                            .Authorization(keymint::TAG_PURPOSE, keymint::KeyPurpose::SIGN)
403                            .Digest(keymint::Digest::SHA_2_256)
404                            .Authorization(keymint::TAG_MAC_LENGTH, kHMACOutputSize);
405 
406     rc = authentication_key.iSecurityLevel->createOperation(
407         authentication_key.metadata.key, sign_params.vector_data(), false /* forced */,
408         &signOperationResponse);
409     if (!rc.isOk()) {
410         std::cerr << "Failed to begin signing operation: " << rc.getDescription() << std::endl;
411         return unwrapError(rc);
412     }
413 
414     std::optional<std::vector<uint8_t>> optMac;
415 
416     rc = signOperationResponse.iOperation->finish(toBeSigned, {}, &optMac);
417     if (!rc.isOk()) {
418         std::cerr << "Failed to finish encryption operation: " << rc.getDescription() << std::endl;
419         return unwrapError(rc);
420     }
421 
422     if (!optMac) {
423         std::cerr << "Signing succeeded but no MAC returned." << std::endl;
424         return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
425     }
426 
427     auto mac = std::move(*optMac);
428 
429     EncryptedData protobuf;
430     protobuf.set_init_vector(initVector.data(), initVector.size());
431     protobuf.set_authentication_data(mac.data(), mac.size());
432     protobuf.set_encrypted_data(ciphertext.data(), ciphertext.size());
433     std::string resultString;
434     if (!protobuf.SerializeToString(&resultString)) {
435         std::cerr << "Encrypt: Failed to serialize EncryptedData protobuf.";
436         return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
437     }
438 
439     std::vector<uint8_t> result(reinterpret_cast<const uint8_t*>(resultString.data()),
440                                 reinterpret_cast<const uint8_t*>(resultString.data()) +
441                                     resultString.size());
442     return result;
443 }
444 
445 std::variant<int, std::vector<uint8_t>>
decryptWithAuthentication(const std::string & name,const std::vector<uint8_t> & data)446 decryptWithAuthentication(const std::string& name, const std::vector<uint8_t>& data) {
447 
448     // Decode encrypted data
449     EncryptedData protobuf;
450     if (!protobuf.ParseFromArray(data.data(), data.size())) {
451         std::cerr << "Decrypt: Failed to parse EncryptedData protobuf." << std::endl;
452         return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
453     }
454 
455     // Load encryption and authentication keys.
456     std::string encryption_key_name = name + kEncryptSuffix;
457     auto encryption_key_result = loadOrCreateAndVerifyEncryptionKey(
458         encryption_key_name, keymint::SecurityLevel::KEYSTORE /* ignored */, false /* create */);
459     if (auto error = std::get_if<int>(&encryption_key_result)) {
460         return *error;
461     }
462     auto encryption_key = std::get<ks2::KeyEntryResponse>(encryption_key_result);
463 
464     std::string authentication_key_name = name + kAuthenticateSuffix;
465     auto authentication_key_result = loadOrCreateAndVerifyAuthenticationKey(
466         authentication_key_name, keymint::SecurityLevel::KEYSTORE /* ignored */,
467         false /* create */);
468     if (auto error = std::get_if<int>(&authentication_key_result)) {
469         return *error;
470     }
471     auto authentication_key = std::get<ks2::KeyEntryResponse>(authentication_key_result);
472 
473     // Begin authentication operation
474     ks2::CreateOperationResponse signOperationResponse;
475     auto sign_params = keymint::AuthorizationSetBuilder()
476                            .Authorization(keymint::TAG_PURPOSE, keymint::KeyPurpose::VERIFY)
477                            .Digest(keymint::Digest::SHA_2_256)
478                            .Authorization(keymint::TAG_MAC_LENGTH, kHMACOutputSize);
479 
480     auto rc = authentication_key.iSecurityLevel->createOperation(
481         authentication_key.metadata.key, sign_params.vector_data(), false /* forced */,
482         &signOperationResponse);
483     if (!rc.isOk()) {
484         std::cerr << "Failed to begin verify operation: " << rc.getDescription() << std::endl;
485         return unwrapError(rc);
486     }
487 
488     const uint8_t* p = reinterpret_cast<const uint8_t*>(protobuf.init_vector().data());
489     std::vector<uint8_t> toBeVerified(p, p + protobuf.init_vector().size());
490 
491     p = reinterpret_cast<const uint8_t*>(protobuf.encrypted_data().data());
492     toBeVerified.insert(toBeVerified.end(), p, p + protobuf.encrypted_data().size());
493 
494     p = reinterpret_cast<const uint8_t*>(protobuf.authentication_data().data());
495     std::vector<uint8_t> signature(p, p + protobuf.authentication_data().size());
496 
497     std::optional<std::vector<uint8_t>> optOut;
498     rc = signOperationResponse.iOperation->finish(toBeVerified, signature, &optOut);
499     if (!rc.isOk()) {
500         std::cerr << "Decrypt: HMAC verification failed: " << rc.getDescription() << std::endl;
501         return unwrapError(rc);
502     }
503 
504     // Begin decryption operation
505     ks2::CreateOperationResponse encOperationResponse;
506     auto encrypt_params = keymint::AuthorizationSetBuilder()
507                               .Authorization(keymint::TAG_PURPOSE, keymint::KeyPurpose::DECRYPT)
508                               .Authorization(keymint::TAG_NONCE, protobuf.init_vector().data(),
509                                              protobuf.init_vector().size())
510                               .Padding(keymint::PaddingMode::PKCS7)
511                               .Authorization(keymint::TAG_BLOCK_MODE, keymint::BlockMode::CBC);
512 
513     rc = encryption_key.iSecurityLevel->createOperation(encryption_key.metadata.key,
514                                                         encrypt_params.vector_data(),
515                                                         false /* forced */, &encOperationResponse);
516     if (!rc.isOk()) {
517         std::cerr << "Failed to begin encryption operation: " << rc.getDescription() << std::endl;
518         return unwrapError(rc);
519     }
520 
521     std::optional<std::vector<uint8_t>> optPlaintext;
522 
523     p = reinterpret_cast<const uint8_t*>(protobuf.encrypted_data().data());
524     std::vector<uint8_t> cyphertext(p, p + protobuf.encrypted_data().size());
525 
526     rc = encOperationResponse.iOperation->finish(cyphertext, {}, &optPlaintext);
527     if (!rc.isOk()) {
528         std::cerr << "Failed to finish encryption operation: " << rc.getDescription() << std::endl;
529         return unwrapError(rc);
530     }
531 
532     if (!optPlaintext) {
533         std::cerr << "Decryption succeeded but no plaintext returned." << std::endl;
534         return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
535     }
536 
537     return *optPlaintext;
538 }
539 
TestKey(const std::string & name,bool required,const std::vector<keymint::KeyParameter> & parameters)540 bool TestKey(const std::string& name, bool required,
541              const std::vector<keymint::KeyParameter>& parameters) {
542     auto keystore = CreateKeystoreInstance();
543     auto sec_level =
544         GetSecurityLevelInterface(keystore, keymint::SecurityLevel::TRUSTED_ENVIRONMENT);
545 
546     ks2::KeyDescriptor keyDescriptor = {
547         .domain = ks2::Domain::APP,
548         .nspace = -1,
549         .alias = "tmp",
550         .blob = {},
551     };
552 
553     ks2::KeyMetadata keyMetadata;
554 
555     auto rc = sec_level->generateKey(keyDescriptor, {} /* attestationKey */, parameters,
556                                      0 /* flags */, {} /* entropy */, &keyMetadata);
557     const char kBoldRedAbort[] = "\033[1;31mABORT\033[0m";
558     if (!rc.isOk()) {
559         LOG(ERROR) << "Failed to generate key: " << rc.getDescription();
560         printf("[%s] %s\n", kBoldRedAbort, name.c_str());
561         return false;
562     }
563 
564     rc = keystore->deleteKey(keyDescriptor);
565     if (!rc.isOk()) {
566         LOG(ERROR) << "Failed to delete key: " << rc.getDescription();
567         printf("[%s] %s\n", kBoldRedAbort, name.c_str());
568         return false;
569     }
570     printf("===============================================================\n");
571     printf("%s Key Characteristics:\n", name.c_str());
572     PrintKeyCharacteristics(keyMetadata.authorizations);
573     bool hardware_backed = std::any_of(keyMetadata.authorizations.begin(),
574                                        keyMetadata.authorizations.end(), isHardwareEnforced);
575     if (std::any_of(keyMetadata.authorizations.begin(), keyMetadata.authorizations.end(),
576                     [&](const auto& a) {
577                         return !isHardwareEnforced(a) &&
578                                (a.keyParameter.tag == keymint::Tag::ALGORITHM ||
579                                 a.keyParameter.tag == keymint::Tag::KEY_SIZE ||
580                                 a.keyParameter.tag == keymint::Tag::RSA_PUBLIC_EXPONENT);
581                     })) {
582         VLOG(1) << "Hardware-backed key but required characteristics enforced in software.";
583         hardware_backed = false;
584     }
585     const char kBoldRedFail[] = "\033[1;31mFAIL\033[0m";
586     const char kBoldGreenPass[] = "\033[1;32mPASS\033[0m";
587     const char kBoldYellowWarn[] = "\033[1;33mWARN\033[0m";
588     printf("[%s] %s\n",
589            hardware_backed ? kBoldGreenPass : (required ? kBoldRedFail : kBoldYellowWarn),
590            name.c_str());
591 
592     return (hardware_backed || !required);
593 }
594 
GetRSASignParameters(uint32_t key_size,bool sha256_only)595 keymint::AuthorizationSet GetRSASignParameters(uint32_t key_size, bool sha256_only) {
596     keymint::AuthorizationSetBuilder parameters;
597     parameters.RsaSigningKey(key_size, 65537)
598         .Digest(keymint::Digest::SHA_2_256)
599         .Padding(keymint::PaddingMode::RSA_PKCS1_1_5_SIGN)
600         .Padding(keymint::PaddingMode::RSA_PSS)
601         .Authorization(keymint::TAG_NO_AUTH_REQUIRED);
602     if (!sha256_only) {
603         parameters.Digest(keymint::Digest::SHA_2_224)
604             .Digest(keymint::Digest::SHA_2_384)
605             .Digest(keymint::Digest::SHA_2_512);
606     }
607     return std::move(parameters);
608 }
609 
GetRSAEncryptParameters(uint32_t key_size)610 keymint::AuthorizationSet GetRSAEncryptParameters(uint32_t key_size) {
611     keymint::AuthorizationSetBuilder parameters;
612     parameters.RsaEncryptionKey(key_size, 65537)
613         .Padding(keymint::PaddingMode::RSA_PKCS1_1_5_ENCRYPT)
614         .Padding(keymint::PaddingMode::RSA_OAEP)
615         .Authorization(keymint::TAG_NO_AUTH_REQUIRED);
616     return std::move(parameters);
617 }
618 
GetECDSAParameters(uint32_t key_size,bool sha256_only)619 keymint::AuthorizationSet GetECDSAParameters(uint32_t key_size, bool sha256_only) {
620     keymint::AuthorizationSetBuilder parameters;
621     parameters.EcdsaSigningKey(key_size)
622         .Digest(keymint::Digest::SHA_2_256)
623         .Authorization(keymint::TAG_NO_AUTH_REQUIRED);
624     if (!sha256_only) {
625         parameters.Digest(keymint::Digest::SHA_2_224)
626             .Digest(keymint::Digest::SHA_2_384)
627             .Digest(keymint::Digest::SHA_2_512);
628     }
629     return std::move(parameters);
630 }
631 
GetAESParameters(uint32_t key_size,bool with_gcm_mode)632 keymint::AuthorizationSet GetAESParameters(uint32_t key_size, bool with_gcm_mode) {
633     keymint::AuthorizationSetBuilder parameters;
634     parameters.AesEncryptionKey(key_size).Authorization(keymint::TAG_NO_AUTH_REQUIRED);
635     if (with_gcm_mode) {
636         parameters.Authorization(keymint::TAG_BLOCK_MODE, keymint::BlockMode::GCM)
637             .Authorization(keymint::TAG_MIN_MAC_LENGTH, 128);
638     } else {
639         parameters.Authorization(keymint::TAG_BLOCK_MODE, keymint::BlockMode::ECB);
640         parameters.Authorization(keymint::TAG_BLOCK_MODE, keymint::BlockMode::CBC);
641         parameters.Authorization(keymint::TAG_BLOCK_MODE, keymint::BlockMode::CTR);
642         parameters.Padding(keymint::PaddingMode::NONE);
643     }
644     return std::move(parameters);
645 }
646 
GetHMACParameters(uint32_t key_size,keymint::Digest digest)647 keymint::AuthorizationSet GetHMACParameters(uint32_t key_size, keymint::Digest digest) {
648     keymint::AuthorizationSetBuilder parameters;
649     parameters.HmacKey(key_size)
650         .Digest(digest)
651         .Authorization(keymint::TAG_MIN_MAC_LENGTH, 224)
652         .Authorization(keymint::TAG_NO_AUTH_REQUIRED);
653     return std::move(parameters);
654 }
655 
GetTestCases()656 std::vector<TestCase> GetTestCases() {
657     TestCase test_cases[] = {
658         {"RSA-2048 Sign", true, GetRSASignParameters(2048, true)},
659         {"RSA-2048 Sign (more digests)", false, GetRSASignParameters(2048, false)},
660         {"RSA-3072 Sign", false, GetRSASignParameters(3072, false)},
661         {"RSA-4096 Sign", false, GetRSASignParameters(4096, false)},
662         {"RSA-2048 Encrypt", true, GetRSAEncryptParameters(2048)},
663         {"RSA-3072 Encrypt", false, GetRSAEncryptParameters(3072)},
664         {"RSA-4096 Encrypt", false, GetRSAEncryptParameters(4096)},
665         {"ECDSA-P256 Sign", true, GetECDSAParameters(256, true)},
666         {"ECDSA-P256 Sign (more digests)", false, GetECDSAParameters(256, false)},
667         {"ECDSA-P224 Sign", false, GetECDSAParameters(224, false)},
668         {"ECDSA-P384 Sign", false, GetECDSAParameters(384, false)},
669         {"ECDSA-P521 Sign", false, GetECDSAParameters(521, false)},
670         {"AES-128", true, GetAESParameters(128, false)},
671         {"AES-256", true, GetAESParameters(256, false)},
672         {"AES-128-GCM", false, GetAESParameters(128, true)},
673         {"AES-256-GCM", false, GetAESParameters(256, true)},
674         {"HMAC-SHA256-16", true, GetHMACParameters(16, keymint::Digest::SHA_2_256)},
675         {"HMAC-SHA256-32", true, GetHMACParameters(32, keymint::Digest::SHA_2_256)},
676         {"HMAC-SHA256-64", false, GetHMACParameters(64, keymint::Digest::SHA_2_256)},
677         {"HMAC-SHA224-32", false, GetHMACParameters(32, keymint::Digest::SHA_2_224)},
678         {"HMAC-SHA384-32", false, GetHMACParameters(32, keymint::Digest::SHA_2_384)},
679         {"HMAC-SHA512-32", false, GetHMACParameters(32, keymint::Digest::SHA_2_512)},
680     };
681     return std::vector<TestCase>(&test_cases[0], &test_cases[arraysize(test_cases)]);
682 }
683 
BrilloPlatformTest(const std::string & prefix,bool test_for_0_3)684 int BrilloPlatformTest(const std::string& prefix, bool test_for_0_3) {
685     const char kBoldYellowWarning[] = "\033[1;33mWARNING\033[0m";
686     if (test_for_0_3) {
687         printf("%s: Testing for keymaster v0.3. "
688                "This does not meet Brillo requirements.\n",
689                kBoldYellowWarning);
690     }
691     int test_count = 0;
692     int fail_count = 0;
693     std::vector<TestCase> test_cases = GetTestCases();
694     for (const auto& test_case : test_cases) {
695         if (!prefix.empty() &&
696             !base::StartsWith(test_case.name, prefix, base::CompareCase::SENSITIVE)) {
697             continue;
698         }
699         if (test_for_0_3 &&
700             (base::StartsWith(test_case.name, "AES", base::CompareCase::SENSITIVE) ||
701              base::StartsWith(test_case.name, "HMAC", base::CompareCase::SENSITIVE))) {
702             continue;
703         }
704         ++test_count;
705         if (!TestKey(test_case.name, test_case.required_for_brillo_pts,
706                      test_case.parameters.vector_data())) {
707             VLOG(1) << "Test failed: " << test_case.name;
708             ++fail_count;
709         }
710     }
711     return fail_count;
712 }
713 
ListTestCases()714 int ListTestCases() {
715     const char kBoldGreenRequired[] = "\033[1;32mREQUIRED\033[0m";
716     const char kBoldYellowRecommended[] = "\033[1;33mRECOMMENDED\033[0m";
717     std::vector<TestCase> test_cases = GetTestCases();
718     for (const auto& test_case : test_cases) {
719         printf("%s : %s\n", test_case.name.c_str(),
720                test_case.required_for_brillo_pts ? kBoldGreenRequired : kBoldYellowRecommended);
721     }
722     return 0;
723 }
724 
ReadFile(const std::string & filename)725 std::vector<uint8_t> ReadFile(const std::string& filename) {
726     std::string content;
727     base::FilePath path(filename);
728     if (!base::ReadFileToString(path, &content)) {
729         printf("Failed to read file: %s\n", filename.c_str());
730         exit(1);
731     }
732     std::vector<uint8_t> buffer(reinterpret_cast<const uint8_t*>(content.data()),
733                                 reinterpret_cast<const uint8_t*>(content.data()) + content.size());
734     return buffer;
735 }
736 
WriteFile(const std::string & filename,const std::vector<uint8_t> & content)737 void WriteFile(const std::string& filename, const std::vector<uint8_t>& content) {
738     base::FilePath path(filename);
739     int size = content.size();
740     if (base::WriteFile(path, reinterpret_cast<const char*>(content.data()), size) != size) {
741         printf("Failed to write file: %s\n", filename.c_str());
742         exit(1);
743     }
744 }
745 
746 // Note: auth_bound keys created with this tool will not be usable.
GenerateKey(const std::string & name,keymint::SecurityLevel securityLevel,bool auth_bound)747 int GenerateKey(const std::string& name, keymint::SecurityLevel securityLevel, bool auth_bound) {
748     auto keystore = CreateKeystoreInstance();
749     auto sec_level = GetSecurityLevelInterface(keystore, securityLevel);
750     keymint::AuthorizationSetBuilder params;
751     params.RsaSigningKey(2048, 65537)
752         .Digest(keymint::Digest::SHA_2_224)
753         .Digest(keymint::Digest::SHA_2_256)
754         .Digest(keymint::Digest::SHA_2_384)
755         .Digest(keymint::Digest::SHA_2_512)
756         .Padding(keymint::PaddingMode::RSA_PKCS1_1_5_SIGN)
757         .Padding(keymint::PaddingMode::RSA_PSS);
758     if (auth_bound) {
759         // Gatekeeper normally generates the secure user id.
760         // Using zero allows the key to be created, but it will not be usuable.
761         params.Authorization(keymint::TAG_USER_SECURE_ID, 0);
762     } else {
763         params.Authorization(keymint::TAG_NO_AUTH_REQUIRED);
764     }
765 
766     ks2::KeyMetadata keyMetadata;
767 
768     auto rc =
769         sec_level->generateKey(keyDescriptor(name), {} /* attestationKey */, params.vector_data(),
770                                0 /* flags */, {} /* entropy */, &keyMetadata);
771 
772     if (!rc.isOk()) {
773         std::cerr << "GenerateKey failed: " << rc.getDescription() << std::endl;
774         return unwrapError(rc);
775     }
776     std::cout << "GenerateKey: success" << std::endl;
777     PrintKeyCharacteristics(keyMetadata.authorizations);
778     return 0;
779 }
780 
GetCharacteristics(const std::string & name)781 int GetCharacteristics(const std::string& name) {
782     auto keystore = CreateKeystoreInstance();
783 
784     ks2::KeyEntryResponse keyEntryResponse;
785 
786     auto rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
787     if (!rc.isOk()) {
788         std::cerr << "Failed to get key entry: " << rc.getDescription() << std::endl;
789         return unwrapError(rc);
790     }
791 
792     std::cout << "GetCharacteristics: success" << std::endl;
793     PrintKeyCharacteristics(keyEntryResponse.metadata.authorizations);
794     return 0;
795 }
796 
ExportKey(const std::string & name)797 int ExportKey(const std::string& name) {
798     auto keystore = CreateKeystoreInstance();
799 
800     ks2::KeyEntryResponse keyEntryResponse;
801 
802     auto rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
803     if (!rc.isOk()) {
804         std::cerr << "Failed to get key entry: " << rc.getDescription() << std::endl;
805         return unwrapError(rc);
806     }
807 
808     if (auto cert = keyEntryResponse.metadata.certificate) {
809         std::cout << "ExportKey: Got certificate of length (" << cert->size() << ")" << std::endl;
810     } else {
811         std::cout << "ExportKey: Key entry does not have a public component.\n";
812         std::cout << "Possibly a symmetric key?" << std::endl;
813     }
814     return 0;
815 }
816 
DeleteKey(const std::string & name)817 int DeleteKey(const std::string& name) {
818     auto keystore = CreateKeystoreInstance();
819 
820     auto rc = keystore->deleteKey(keyDescriptor(name));
821     if (!rc.isOk()) {
822         std::cerr << "Failed to delete key: " << rc.getDescription();
823         return unwrapError(rc);
824     }
825     std::cout << "Successfully deleted key." << std::endl;
826     return 0;
827 }
828 
DoesKeyExist(const std::string & name)829 int DoesKeyExist(const std::string& name) {
830     auto keystore = CreateKeystoreInstance();
831     ks2::KeyEntryResponse keyEntryResponse;
832 
833     bool keyExists = true;
834     auto rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
835     if (!rc.isOk()) {
836         auto responseCode = unwrapError(rc);
837         if (ks2::ResponseCode(responseCode) == ks2::ResponseCode::KEY_NOT_FOUND) {
838             keyExists = false;
839         } else {
840             std::cerr << "Failed to get key entry: " << rc.getDescription() << std::endl;
841             return unwrapError(rc);
842         }
843     }
844     std::cout << "DoesKeyExists: " << (keyExists ? "yes" : "no") << std::endl;
845     return 0;
846 }
847 
List()848 int List() {
849     auto keystore = CreateKeystoreInstance();
850     std::vector<ks2::KeyDescriptor> key_list;
851     auto rc = keystore->listEntries(ks2::Domain::APP, -1 /* nspace ignored */, &key_list);
852     if (!rc.isOk()) {
853         std::cerr << "ListKeys failed: " << rc.getDescription() << std::endl;
854         return unwrapError(rc);
855     }
856     std::cout << "Keys:\n";
857     for (const auto& key : key_list) {
858         std::cout << "  "
859                   << (key.alias ? *key.alias : "Whoopsi - no alias, this should not happen.")
860                   << std::endl;
861     }
862     return 0;
863 }
864 
SignAndVerify(const std::string & name)865 int SignAndVerify(const std::string& name) {
866     auto keystore = CreateKeystoreInstance();
867     auto sign_params = keymint::AuthorizationSetBuilder()
868                            .Authorization(keymint::TAG_PURPOSE, keymint::KeyPurpose::SIGN)
869                            .Padding(keymint::PaddingMode::RSA_PKCS1_1_5_SIGN)
870                            .Digest(keymint::Digest::SHA_2_256);
871 
872     keymint::AuthorizationSet output_params;
873 
874     ks2::KeyEntryResponse keyEntryResponse;
875 
876     auto rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
877     if (!rc.isOk()) {
878         std::cerr << "Failed to get key entry: " << rc.getDescription() << std::endl;
879         return unwrapError(rc);
880     }
881 
882     ks2::CreateOperationResponse operationResponse;
883 
884     rc = keyEntryResponse.iSecurityLevel->createOperation(keyEntryResponse.metadata.key,
885                                                           sign_params.vector_data(),
886                                                           false /* forced */, &operationResponse);
887     if (!rc.isOk()) {
888         std::cerr << "Failed to create operation: " << rc.getDescription() << std::endl;
889         return unwrapError(rc);
890     }
891 
892     const std::vector<uint8_t> data_to_sign{0x64, 0x61, 0x74, 0x61, 0x5f, 0x74,
893                                             0x6f, 0x5f, 0x73, 0x69, 0x67, 0x6e};
894     std::optional<std::vector<uint8_t>> output_data;
895     rc = operationResponse.iOperation->finish(data_to_sign, {}, &output_data);
896     if (!rc.isOk()) {
897         std::cerr << "Failed to finalize operation: " << rc.getDescription() << std::endl;
898         return unwrapError(rc);
899     }
900 
901     if (!output_data) {
902         std::cerr << "Odd signing succeeded but no signature was returned." << std::endl;
903         return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
904     }
905     auto signature = std::move(*output_data);
906 
907     std::cout << "Sign: " << signature.size() << " bytes." << std::endl;
908 
909     if (auto cert = keyEntryResponse.metadata.certificate) {
910         const uint8_t* p = cert->data();
911         bssl::UniquePtr<X509> decoded_cert(d2i_X509(nullptr, &p, (long)cert->size()));
912         bssl::UniquePtr<EVP_PKEY> decoded_pkey(X509_get_pubkey(decoded_cert.get()));
913         bssl::UniquePtr<EVP_MD_CTX> ctx(EVP_MD_CTX_new());
914         if (!ctx) {
915             std::cerr << "Failed to created EVP_MD context. << std::endl";
916             return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
917         }
918 
919         if (!EVP_DigestVerifyInit(ctx.get(), nullptr, EVP_sha256(), nullptr, decoded_pkey.get()) ||
920             !EVP_DigestVerifyUpdate(ctx.get(), data_to_sign.data(), data_to_sign.size()) ||
921             EVP_DigestVerifyFinal(ctx.get(), signature.data(), signature.size()) != 1) {
922             std::cerr << "Failed to verify signature." << std::endl;
923             return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
924         }
925     } else {
926         std::cerr << "No public key to check signature against." << std::endl;
927         return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
928     }
929 
930     std::cout << "Verify: OK" << std::endl;
931     return 0;
932 }
933 
Encrypt(const std::string & key_name,const std::string & input_filename,const std::string & output_filename,keymint::SecurityLevel securityLevel)934 int Encrypt(const std::string& key_name, const std::string& input_filename,
935             const std::string& output_filename, keymint::SecurityLevel securityLevel) {
936     auto input = ReadFile(input_filename);
937     auto result = encryptWithAuthentication(key_name, input, securityLevel);
938     if (auto error = std::get_if<int>(&result)) {
939         std::cerr << "EncryptWithAuthentication failed." << std::endl;
940         return *error;
941     }
942     WriteFile(output_filename, std::get<std::vector<uint8_t>>(result));
943     return 0;
944 }
945 
Decrypt(const std::string & key_name,const std::string & input_filename,const std::string & output_filename)946 int Decrypt(const std::string& key_name, const std::string& input_filename,
947             const std::string& output_filename) {
948     auto input = ReadFile(input_filename);
949     auto result = decryptWithAuthentication(key_name, input);
950     if (auto error = std::get_if<int>(&result)) {
951         std::cerr << "DecryptWithAuthentication failed." << std::endl;
952         return *error;
953     }
954     WriteFile(output_filename, std::get<std::vector<uint8_t>>(result));
955     return 0;
956 }
957 
securityLevelOption2SecurlityLevel(const CommandLine & cmd)958 keymint::SecurityLevel securityLevelOption2SecurlityLevel(const CommandLine& cmd) {
959     if (cmd.HasSwitch("seclevel")) {
960         auto str = cmd.GetSwitchValueASCII("seclevel");
961         if (str == "strongbox") {
962             return keymint::SecurityLevel::STRONGBOX;
963         } else if (str == "tee") {
964             return keymint::SecurityLevel::TRUSTED_ENVIRONMENT;
965         }
966         std::cerr << "Unknown Security level: " << str << std::endl;
967         std::cerr << "Supported security levels: \"strongbox\" or \"tee\" (default)" << std::endl;
968     }
969     return keymint::SecurityLevel::TRUSTED_ENVIRONMENT;
970 }
971 
972 class ConfirmationListener
973     : public apc::BnConfirmationCallback,
974       public std::promise<std::tuple<apc::ResponseCode, std::optional<std::vector<uint8_t>>>> {
975   public:
ConfirmationListener()976     ConfirmationListener() {}
977 
978     virtual ::ndk::ScopedAStatus
onCompleted(::aidl::android::security::apc::ResponseCode result,const std::optional<std::vector<uint8_t>> & dataConfirmed)979     onCompleted(::aidl::android::security::apc::ResponseCode result,
980                 const std::optional<std::vector<uint8_t>>& dataConfirmed) override {
981         this->set_value({result, dataConfirmed});
982         return ::ndk::ScopedAStatus::ok();
983     };
984 };
985 
Confirmation(const std::string & promptText,const std::string & extraDataHex,const std::string & locale,const std::string & uiOptionsStr,const std::string & cancelAfter)986 int Confirmation(const std::string& promptText, const std::string& extraDataHex,
987                  const std::string& locale, const std::string& uiOptionsStr,
988                  const std::string& cancelAfter) {
989     ::ndk::SpAIBinder apcBinder(AServiceManager_getService("android.security.apc"));
990     auto apcService = apc::IProtectedConfirmation::fromBinder(apcBinder);
991     if (!apcService) {
992         std::cerr << "Error: could not connect to apc service." << std::endl;
993         return 1;
994     }
995 
996     if (promptText.size() == 0) {
997         printf("The --prompt_text parameter cannot be empty.\n");
998         return 1;
999     }
1000 
1001     std::vector<uint8_t> extraData;
1002     if (!base::HexStringToBytes(extraDataHex, &extraData)) {
1003         printf("The --extra_data parameter does not appear to be valid hexadecimal.\n");
1004         return 1;
1005     }
1006 
1007     std::vector<std::string> pieces =
1008         base::SplitString(uiOptionsStr, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
1009     int uiOptionsAsFlags = 0;
1010     for (auto& p : pieces) {
1011         int value;
1012         if (!base::StringToInt(p, &value)) {
1013             printf("Error parsing %s in --ui_options parameter as a number.\n", p.c_str());
1014             return 1;
1015         }
1016         uiOptionsAsFlags |= (1 << value);
1017     }
1018 
1019     double cancelAfterValue = 0.0;
1020 
1021     if (cancelAfter.size() > 0 && !base::StringToDouble(cancelAfter, &cancelAfterValue)) {
1022         printf("Error parsing %s in --cancel_after parameter as a double.\n", cancelAfter.c_str());
1023         return 1;
1024     }
1025 
1026     auto listener = std::make_shared<ConfirmationListener>();
1027 
1028     auto future = listener->get_future();
1029     auto rc = apcService->presentPrompt(listener, promptText, extraData, locale, uiOptionsAsFlags);
1030 
1031     if (!rc.isOk()) {
1032         std::cerr << "Presenting confirmation prompt failed: " << rc.getDescription() << std::endl;
1033         return 1;
1034     }
1035 
1036     std::cerr << "Waiting for prompt to complete - use Ctrl+C to abort..." << std::endl;
1037 
1038     if (cancelAfterValue > 0.0) {
1039         std::cerr << "Sleeping " << cancelAfterValue << " seconds before canceling prompt..."
1040                   << std::endl;
1041         auto fstatus =
1042             future.wait_for(std::chrono::milliseconds(uint64_t(cancelAfterValue * 1000)));
1043         if (fstatus == std::future_status::timeout) {
1044             rc = apcService->cancelPrompt(listener);
1045             if (!rc.isOk()) {
1046                 std::cerr << "Canceling confirmation prompt failed: " << rc.getDescription()
1047                           << std::endl;
1048                 return 1;
1049             }
1050         }
1051     }
1052 
1053     future.wait();
1054 
1055     auto [responseCode, dataThatWasConfirmed] = future.get();
1056 
1057     std::cerr << "Confirmation prompt completed\n"
1058               << "responseCode = " << toString(responseCode);
1059     size_t newLineCountDown = 16;
1060     bool hasPrinted = false;
1061     if (dataThatWasConfirmed) {
1062         std::cerr << "dataThatWasConfirmed[" << dataThatWasConfirmed->size() << "] = {";
1063         for (uint8_t element : *dataThatWasConfirmed) {
1064             if (hasPrinted) {
1065                 std::cerr << ", ";
1066             }
1067             if (newLineCountDown == 0) {
1068                 std::cerr << "\n  ";
1069                 newLineCountDown = 32;
1070             }
1071             std::cerr << "0x" << std::hex << std::setw(2) << std::setfill('0') << (unsigned)element;
1072 
1073             hasPrinted = true;
1074         }
1075     }
1076     std::cerr << std::endl;
1077     return 0;
1078 }
1079 
1080 }  // namespace
1081 
main(int argc,char ** argv)1082 int main(int argc, char** argv) {
1083     CommandLine::Init(argc, argv);
1084     CommandLine* command_line = CommandLine::ForCurrentProcess();
1085     CommandLine::StringVector args = command_line->GetArgs();
1086 
1087     ABinderProcess_startThreadPool();
1088 
1089     if (args.empty()) {
1090         PrintUsageAndExit();
1091     }
1092     if (args[0] == "brillo-platform-test") {
1093         return BrilloPlatformTest(command_line->GetSwitchValueASCII("prefix"),
1094                                   command_line->HasSwitch("test_for_0_3"));
1095     } else if (args[0] == "list-brillo-tests") {
1096         return ListTestCases();
1097     } else if (args[0] == "generate") {
1098         return GenerateKey(command_line->GetSwitchValueASCII("name"),
1099                            securityLevelOption2SecurlityLevel(*command_line),
1100                            command_line->HasSwitch("auth_bound"));
1101     } else if (args[0] == "get-chars") {
1102         return GetCharacteristics(command_line->GetSwitchValueASCII("name"));
1103     } else if (args[0] == "export") {
1104         return ExportKey(command_line->GetSwitchValueASCII("name"));
1105     } else if (args[0] == "delete") {
1106         return DeleteKey(command_line->GetSwitchValueASCII("name"));
1107     } else if (args[0] == "exists") {
1108         return DoesKeyExist(command_line->GetSwitchValueASCII("name"));
1109     } else if (args[0] == "list") {
1110         return List();
1111     } else if (args[0] == "sign-verify") {
1112         return SignAndVerify(command_line->GetSwitchValueASCII("name"));
1113     } else if (args[0] == "encrypt") {
1114         return Encrypt(command_line->GetSwitchValueASCII("name"),
1115                        command_line->GetSwitchValueASCII("in"),
1116                        command_line->GetSwitchValueASCII("out"),
1117                        securityLevelOption2SecurlityLevel(*command_line));
1118     } else if (args[0] == "decrypt") {
1119         return Decrypt(command_line->GetSwitchValueASCII("name"),
1120                        command_line->GetSwitchValueASCII("in"),
1121                        command_line->GetSwitchValueASCII("out"));
1122     } else if (args[0] == "confirmation") {
1123         return Confirmation(command_line->GetSwitchValueNative("prompt_text"),
1124                             command_line->GetSwitchValueASCII("extra_data"),
1125                             command_line->GetSwitchValueASCII("locale"),
1126                             command_line->GetSwitchValueASCII("ui_options"),
1127                             command_line->GetSwitchValueASCII("cancel_after"));
1128     } else {
1129         PrintUsageAndExit();
1130     }
1131     return 0;
1132 }
1133