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