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