1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "keystore" 18 19#include "keystore.h" 20 21#include <dirent.h> 22#include <fcntl.h> 23 24#include <openssl/bio.h> 25 26#include <utils/String16.h> 27#include <utils/String8.h> 28 29#include <keystore/IKeystoreService.h> 30 31#include <android/hardware/keymaster/3.0/IKeymasterDevice.h> 32 33#include "keystore_utils.h" 34#include "permissions.h" 35#include <keystore/keystore_hidl_support.h> 36 37const char* KeyStore::sOldMasterKey = ".masterkey"; 38const char* KeyStore::sMetaDataFile = ".metadata"; 39 40const android::String16 KeyStore::sRSAKeyType("RSA"); 41 42using namespace keystore; 43using android::String8; 44 45KeyStore::KeyStore(Entropy* entropy, const km_device_t& device, const km_device_t& fallback, 46 bool allowNewFallback) 47 : mEntropy(entropy), mDevice(device), mFallbackDevice(fallback), 48 mAllowNewFallback(allowNewFallback) { 49 memset(&mMetaData, '\0', sizeof(mMetaData)); 50} 51 52KeyStore::~KeyStore() { 53 for (android::Vector<UserState*>::iterator it(mMasterKeys.begin()); it != mMasterKeys.end(); 54 it++) { 55 delete *it; 56 } 57 mMasterKeys.clear(); 58} 59 60ResponseCode KeyStore::initialize() { 61 readMetaData(); 62 if (upgradeKeystore()) { 63 writeMetaData(); 64 } 65 66 return ResponseCode::NO_ERROR; 67} 68 69ResponseCode KeyStore::initializeUser(const android::String8& pw, uid_t userId) { 70 UserState* userState = getUserState(userId); 71 return userState->initialize(pw, mEntropy); 72} 73 74ResponseCode KeyStore::copyMasterKey(uid_t srcUser, uid_t dstUser) { 75 UserState* userState = getUserState(dstUser); 76 UserState* initState = getUserState(srcUser); 77 return userState->copyMasterKey(initState); 78} 79 80ResponseCode KeyStore::writeMasterKey(const android::String8& pw, uid_t userId) { 81 UserState* userState = getUserState(userId); 82 return userState->writeMasterKey(pw, mEntropy); 83} 84 85ResponseCode KeyStore::readMasterKey(const android::String8& pw, uid_t userId) { 86 UserState* userState = getUserState(userId); 87 return userState->readMasterKey(pw, mEntropy); 88} 89 90/* Here is the encoding of keys. This is necessary in order to allow arbitrary 91 * characters in keys. Characters in [0-~] are not encoded. Others are encoded 92 * into two bytes. The first byte is one of [+-.] which represents the first 93 * two bits of the character. The second byte encodes the rest of the bits into 94 * [0-o]. Therefore in the worst case the length of a key gets doubled. Note 95 * that Base64 cannot be used here due to the need of prefix match on keys. */ 96 97static size_t encode_key_length(const android::String8& keyName) { 98 const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string()); 99 size_t length = keyName.length(); 100 for (int i = length; i > 0; --i, ++in) { 101 if (*in < '0' || *in > '~') { 102 ++length; 103 } 104 } 105 return length; 106} 107 108static int encode_key(char* out, const android::String8& keyName) { 109 const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string()); 110 size_t length = keyName.length(); 111 for (int i = length; i > 0; --i, ++in, ++out) { 112 if (*in < '0' || *in > '~') { 113 *out = '+' + (*in >> 6); 114 *++out = '0' + (*in & 0x3F); 115 ++length; 116 } else { 117 *out = *in; 118 } 119 } 120 *out = '\0'; 121 return length; 122} 123 124android::String8 KeyStore::getKeyName(const android::String8& keyName, const BlobType type) { 125 std::vector<char> encoded(encode_key_length(keyName) + 1); // add 1 for null char 126 encode_key(encoded.data(), keyName); 127 if (type == TYPE_KEY_CHARACTERISTICS) { 128 return android::String8::format(".chr_%s", encoded.data()); 129 } else { 130 return android::String8(encoded.data()); 131 } 132} 133 134android::String8 KeyStore::getKeyNameForUid( 135 const android::String8& keyName, uid_t uid, const BlobType type) { 136 std::vector<char> encoded(encode_key_length(keyName) + 1); // add 1 for null char 137 encode_key(encoded.data(), keyName); 138 if (type == TYPE_KEY_CHARACTERISTICS) { 139 return android::String8::format(".%u_chr_%s", uid, encoded.data()); 140 } else { 141 return android::String8::format("%u_%s", uid, encoded.data()); 142 } 143} 144 145android::String8 KeyStore::getKeyNameForUidWithDir( 146 const android::String8& keyName, uid_t uid, const BlobType type) { 147 std::vector<char> encoded(encode_key_length(keyName) + 1); // add 1 for null char 148 encode_key(encoded.data(), keyName); 149 150 if (type == TYPE_KEY_CHARACTERISTICS) { 151 return android::String8::format("%s/.%u_chr_%s", getUserStateByUid(uid)->getUserDirName(), 152 uid, encoded.data()); 153 } else { 154 return android::String8::format("%s/%u_%s", getUserStateByUid(uid)->getUserDirName(), uid, 155 encoded.data()); 156 } 157} 158 159NullOr<android::String8> KeyStore::getBlobFileNameIfExists(const android::String8& alias, uid_t uid, 160 const BlobType type) { 161 android::String8 filepath8(getKeyNameForUidWithDir(alias, uid, type)); 162 163 if (!access(filepath8.string(), R_OK | W_OK)) return filepath8; 164 165 // If this is one of the legacy UID->UID mappings, use it. 166 uid_t euid = get_keystore_euid(uid); 167 if (euid != uid) { 168 filepath8 = getKeyNameForUidWithDir(alias, euid, type); 169 if (!access(filepath8.string(), R_OK | W_OK)) return filepath8; 170 } 171 172 // They might be using a granted key. 173 auto grant = mGrants.get(uid, alias.string()); 174 if (grant) { 175 filepath8 = String8::format("%s/%s", grant->owner_dir_name_.c_str(), 176 getKeyNameForUid(String8(grant->alias_.c_str()), grant->owner_uid_, type).c_str()); 177 if (!access(filepath8.string(), R_OK | W_OK)) return filepath8; 178 } 179 return {}; 180} 181 182 183void KeyStore::resetUser(uid_t userId, bool keepUnenryptedEntries) { 184 android::String8 prefix(""); 185 android::Vector<android::String16> aliases; 186 UserState* userState = getUserState(userId); 187 if (list(prefix, &aliases, userId) != ResponseCode::NO_ERROR) { 188 return; 189 } 190 for (uint32_t i = 0; i < aliases.size(); i++) { 191 android::String8 filename(aliases[i]); 192 filename = android::String8::format("%s/%s", userState->getUserDirName(), 193 getKeyName(filename, TYPE_ANY).string()); 194 bool shouldDelete = true; 195 if (keepUnenryptedEntries) { 196 Blob blob; 197 ResponseCode rc = get(filename, &blob, ::TYPE_ANY, userId); 198 199 switch (rc) { 200 case ResponseCode::SYSTEM_ERROR: 201 case ResponseCode::VALUE_CORRUPTED: 202 // If we can't read blobs, delete them. 203 shouldDelete = true; 204 break; 205 206 case ResponseCode::NO_ERROR: 207 case ResponseCode::LOCKED: 208 // Delete encrypted blobs but keep unencrypted blobs and super-encrypted blobs. We 209 // need to keep super-encrypted blobs so we can report that the user is 210 // unauthenticated if a caller tries to use them, rather than reporting that they 211 // don't exist. 212 shouldDelete = blob.isEncrypted(); 213 break; 214 215 default: 216 ALOGE("Got unexpected return code %d from KeyStore::get()", rc); 217 // This shouldn't happen. To be on the safe side, delete it. 218 shouldDelete = true; 219 break; 220 } 221 } 222 if (shouldDelete) { 223 del(filename, ::TYPE_ANY, userId); 224 225 // del() will fail silently if no cached characteristics are present for this alias. 226 android::String8 chr_filename(aliases[i]); 227 chr_filename = android::String8::format("%s/%s", userState->getUserDirName(), 228 getKeyName(chr_filename, 229 TYPE_KEY_CHARACTERISTICS).string()); 230 del(chr_filename, ::TYPE_KEY_CHARACTERISTICS, userId); 231 } 232 } 233 if (!userState->deleteMasterKey()) { 234 ALOGE("Failed to delete user %d's master key", userId); 235 } 236 if (!keepUnenryptedEntries) { 237 if (!userState->reset()) { 238 ALOGE("Failed to remove user %d's directory", userId); 239 } 240 } 241} 242 243bool KeyStore::isEmpty(uid_t userId) const { 244 const UserState* userState = getUserState(userId); 245 if (userState == NULL) { 246 return true; 247 } 248 249 DIR* dir = opendir(userState->getUserDirName()); 250 if (!dir) { 251 return true; 252 } 253 254 bool result = true; 255 struct dirent* file; 256 while ((file = readdir(dir)) != NULL) { 257 // We only care about files. 258 if (file->d_type != DT_REG) { 259 continue; 260 } 261 262 // Skip anything that starts with a "." 263 if (file->d_name[0] == '.') { 264 continue; 265 } 266 267 result = false; 268 break; 269 } 270 closedir(dir); 271 return result; 272} 273 274void KeyStore::lock(uid_t userId) { 275 UserState* userState = getUserState(userId); 276 userState->zeroizeMasterKeysInMemory(); 277 userState->setState(STATE_LOCKED); 278} 279 280ResponseCode KeyStore::get(const char* filename, Blob* keyBlob, const BlobType type, uid_t userId) { 281 UserState* userState = getUserState(userId); 282 ResponseCode rc = 283 keyBlob->readBlob(filename, userState->getEncryptionKey(), userState->getState()); 284 if (rc != ResponseCode::NO_ERROR) { 285 return rc; 286 } 287 288 const uint8_t version = keyBlob->getVersion(); 289 if (version < CURRENT_BLOB_VERSION) { 290 /* If we upgrade the key, we need to write it to disk again. Then 291 * it must be read it again since the blob is encrypted each time 292 * it's written. 293 */ 294 if (upgradeBlob(filename, keyBlob, version, type, userId)) { 295 if ((rc = this->put(filename, keyBlob, userId)) != ResponseCode::NO_ERROR || 296 (rc = keyBlob->readBlob(filename, userState->getEncryptionKey(), 297 userState->getState())) != ResponseCode::NO_ERROR) { 298 return rc; 299 } 300 } 301 } 302 303 /* 304 * This will upgrade software-backed keys to hardware-backed keys. 305 */ 306 if (rc == ResponseCode::NO_ERROR && type == TYPE_KEY_PAIR && keyBlob->isFallback()) { 307 ResponseCode imported = 308 importKey(keyBlob->getValue(), keyBlob->getLength(), filename, userId, 309 keyBlob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE); 310 311 // The HAL allowed the import, reget the key to have the "fresh" version. 312 if (imported == ResponseCode::NO_ERROR) { 313 rc = get(filename, keyBlob, TYPE_KEY_PAIR, userId); 314 } 315 } 316 317 // Keymaster 0.3 keys are valid keymaster 1.0 keys, so silently upgrade. 318 if (keyBlob->getType() == TYPE_KEY_PAIR) { 319 keyBlob->setType(TYPE_KEYMASTER_10); 320 rc = this->put(filename, keyBlob, userId); 321 } 322 323 if (type != TYPE_ANY && keyBlob->getType() != type) { 324 ALOGW("key found but type doesn't match: %d vs %d", keyBlob->getType(), type); 325 return ResponseCode::KEY_NOT_FOUND; 326 } 327 328 return rc; 329} 330 331ResponseCode KeyStore::put(const char* filename, Blob* keyBlob, uid_t userId) { 332 UserState* userState = getUserState(userId); 333 return keyBlob->writeBlob(filename, userState->getEncryptionKey(), userState->getState(), 334 mEntropy); 335} 336 337static NullOr<std::tuple<uid_t, std::string>> filename2UidAlias(const std::string& filename); 338 339ResponseCode KeyStore::del(const char* filename, const BlobType type, uid_t userId) { 340 Blob keyBlob; 341 auto uidAlias = filename2UidAlias(filename); 342 uid_t uid; 343 std::string alias; 344 if (uidAlias.isOk()) { 345 std::tie(uid, alias) = std::move(uidAlias).value(); 346 } 347 ResponseCode rc = get(filename, &keyBlob, type, userId); 348 if (rc == ResponseCode::VALUE_CORRUPTED) { 349 // The file is corrupt, the best we can do is rm it. 350 if (uidAlias.isOk()) { 351 // remove possible grants 352 mGrants.removeAllGrantsToKey(uid, alias); 353 } 354 return (unlink(filename) && errno != ENOENT) ? 355 ResponseCode::SYSTEM_ERROR : ResponseCode::NO_ERROR; 356 } 357 if (rc != ResponseCode::NO_ERROR) { 358 return rc; 359 } 360 361 auto& dev = getDevice(keyBlob); 362 363 if (keyBlob.getType() == ::TYPE_KEY_PAIR || keyBlob.getType() == ::TYPE_KEYMASTER_10) { 364 auto ret = KS_HANDLE_HIDL_ERROR(dev->deleteKey(blob2hidlVec(keyBlob))); 365 366 // A device doesn't have to implement delete_key. 367 if (ret != ErrorCode::OK && ret != ErrorCode::UNIMPLEMENTED) 368 return ResponseCode::SYSTEM_ERROR; 369 } 370 371 rc = (unlink(filename) && errno != ENOENT) ? 372 ResponseCode::SYSTEM_ERROR : ResponseCode::NO_ERROR; 373 374 if (rc == ResponseCode::NO_ERROR && keyBlob.getType() != ::TYPE_KEY_CHARACTERISTICS) { 375 // now that we have successfully deleted a key, let's make sure there are no stale grants 376 if (uidAlias.isOk()) { 377 mGrants.removeAllGrantsToKey(uid, alias); 378 } 379 } 380 return rc; 381} 382 383/* 384 * Converts from the "escaped" format on disk to actual name. 385 * This will be smaller than the input string. 386 * 387 * Characters that should combine with the next at the end will be truncated. 388 */ 389static size_t decode_key_length(const char* in, size_t length) { 390 size_t outLength = 0; 391 392 for (const char* end = in + length; in < end; in++) { 393 /* This combines with the next character. */ 394 if (*in < '0' || *in > '~') { 395 continue; 396 } 397 398 outLength++; 399 } 400 return outLength; 401} 402 403static void decode_key(char* out, const char* in, size_t length) { 404 for (const char* end = in + length; in < end; in++) { 405 if (*in < '0' || *in > '~') { 406 /* Truncate combining characters at the end. */ 407 if (in + 1 >= end) { 408 break; 409 } 410 411 *out = (*in++ - '+') << 6; 412 *out++ |= (*in - '0') & 0x3F; 413 } else { 414 *out++ = *in; 415 } 416 } 417 *out = '\0'; 418} 419 420static NullOr<std::tuple<uid_t, std::string>> filename2UidAlias(const std::string& filepath) { 421 auto filenamebase = filepath.find_last_of('/'); 422 std::string filename = filenamebase == std::string::npos ? filepath : 423 filepath.substr(filenamebase + 1); 424 425 if (filename[0] == '.') return {}; 426 427 auto sep = filename.find('_'); 428 if (sep == std::string::npos) return {}; 429 430 std::stringstream s(filename.substr(0, sep)); 431 uid_t uid; 432 s >> uid; 433 if (!s) return {}; 434 435 auto alias = filename.substr(sep + 1); 436 437 std::vector<char> alias_buffer(decode_key_length(alias.c_str(), alias.size()) + 1); 438 439 decode_key(alias_buffer.data(), alias.c_str(), alias.size()); 440 return std::tuple<uid_t, std::string>(uid, alias_buffer.data()); 441} 442 443ResponseCode KeyStore::list(const android::String8& prefix, 444 android::Vector<android::String16>* matches, uid_t userId) { 445 446 UserState* userState = getUserState(userId); 447 size_t n = prefix.length(); 448 449 DIR* dir = opendir(userState->getUserDirName()); 450 if (!dir) { 451 ALOGW("can't open directory for user: %s", strerror(errno)); 452 return ResponseCode::SYSTEM_ERROR; 453 } 454 455 struct dirent* file; 456 while ((file = readdir(dir)) != NULL) { 457 // We only care about files. 458 if (file->d_type != DT_REG) { 459 continue; 460 } 461 462 // Skip anything that starts with a "." 463 if (file->d_name[0] == '.') { 464 continue; 465 } 466 467 if (!strncmp(prefix.string(), file->d_name, n)) { 468 const char* p = &file->d_name[n]; 469 size_t plen = strlen(p); 470 471 size_t extra = decode_key_length(p, plen); 472 char* match = (char*)malloc(extra + 1); 473 if (match != NULL) { 474 decode_key(match, p, plen); 475 matches->push(android::String16(match, extra)); 476 free(match); 477 } else { 478 ALOGW("could not allocate match of size %zd", extra); 479 } 480 } 481 } 482 closedir(dir); 483 return ResponseCode::NO_ERROR; 484} 485 486std::string KeyStore::addGrant(const char* alias, uid_t granterUid, uid_t granteeUid) { 487 return mGrants.put(granteeUid, alias, getUserStateByUid(granterUid)->getUserDirName(), 488 granterUid); 489} 490 491bool KeyStore::removeGrant(const char* alias, const uid_t granterUid, const uid_t granteeUid) { 492 return mGrants.removeByFileAlias(granteeUid, granterUid, alias); 493} 494void KeyStore::removeAllGrantsToUid(const uid_t granteeUid) { 495 mGrants.removeAllGrantsToUid(granteeUid); 496} 497 498ResponseCode KeyStore::importKey(const uint8_t* key, size_t keyLen, const char* filename, 499 uid_t userId, int32_t flags) { 500 Unique_PKCS8_PRIV_KEY_INFO pkcs8(d2i_PKCS8_PRIV_KEY_INFO(NULL, &key, keyLen)); 501 if (!pkcs8.get()) { 502 return ResponseCode::SYSTEM_ERROR; 503 } 504 Unique_EVP_PKEY pkey(EVP_PKCS82PKEY(pkcs8.get())); 505 if (!pkey.get()) { 506 return ResponseCode::SYSTEM_ERROR; 507 } 508 int type = EVP_PKEY_type(pkey->type); 509 AuthorizationSet params; 510 add_legacy_key_authorizations(type, ¶ms); 511 switch (type) { 512 case EVP_PKEY_RSA: 513 params.push_back(TAG_ALGORITHM, Algorithm::RSA); 514 break; 515 case EVP_PKEY_EC: 516 params.push_back(TAG_ALGORITHM, Algorithm::EC); 517 break; 518 default: 519 ALOGW("Unsupported key type %d", type); 520 return ResponseCode::SYSTEM_ERROR; 521 } 522 523 AuthorizationSet opParams(params); 524 hidl_vec<uint8_t> blob; 525 526 ErrorCode error; 527 auto hidlCb = [&] (ErrorCode ret, const hidl_vec<uint8_t>& keyBlob, 528 const KeyCharacteristics& /* ignored */) { 529 error = ret; 530 if (error != ErrorCode::OK) return; 531 blob = keyBlob; 532 }; 533 auto input = blob2hidlVec(key, keyLen); 534 535 ErrorCode rc = KS_HANDLE_HIDL_ERROR( 536 mDevice->importKey(params.hidl_data(), KeyFormat::PKCS8, input, hidlCb)); 537 if (rc != ErrorCode::OK) return ResponseCode::SYSTEM_ERROR; 538 if (error != ErrorCode::OK) { 539 ALOGE("Keymaster error %d importing key pair", error); 540 return ResponseCode::SYSTEM_ERROR; 541 } 542 543 Blob keyBlob(&blob[0], blob.size(), NULL, 0, TYPE_KEYMASTER_10); 544 545 keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 546 keyBlob.setFallback(false); 547 548 return put(filename, &keyBlob, userId); 549} 550 551bool KeyStore::isHardwareBacked(const android::String16& /*keyType*/) const { 552 using ::android::hardware::hidl_string; 553 if (mDevice == NULL) { 554 ALOGW("can't get keymaster device"); 555 return false; 556 } 557 558 bool isSecure = false; 559 auto hidlcb = [&] (bool _isSecure, bool, bool, bool, bool, const hidl_string&, 560 const hidl_string&) { 561 isSecure = _isSecure; 562 }; 563 auto rc = mDevice->getHardwareFeatures(hidlcb); 564 if (!rc.isOk()) { 565 ALOGE("Communication with keymaster HAL failed while retrieving hardware features (%s)", 566 rc.description().c_str()); 567 return false; 568 } 569 return isSecure; 570} 571 572ResponseCode KeyStore::getKeyForName(Blob* keyBlob, const android::String8& keyName, 573 const uid_t uid, const BlobType type) { 574 auto filepath8 = getBlobFileNameIfExists(keyName, uid, type); 575 uid_t userId = get_user_id(uid); 576 577 if (filepath8.isOk()) 578 return get(filepath8.value().string(), keyBlob, type, userId); 579 580 return ResponseCode::KEY_NOT_FOUND; 581} 582 583UserState* KeyStore::getUserState(uid_t userId) { 584 for (android::Vector<UserState*>::iterator it(mMasterKeys.begin()); it != mMasterKeys.end(); 585 it++) { 586 UserState* state = *it; 587 if (state->getUserId() == userId) { 588 return state; 589 } 590 } 591 592 UserState* userState = new UserState(userId); 593 if (!userState->initialize()) { 594 /* There's not much we can do if initialization fails. Trying to 595 * unlock the keystore for that user will fail as well, so any 596 * subsequent request for this user will just return SYSTEM_ERROR. 597 */ 598 ALOGE("User initialization failed for %u; subsuquent operations will fail", userId); 599 } 600 mMasterKeys.add(userState); 601 return userState; 602} 603 604UserState* KeyStore::getUserStateByUid(uid_t uid) { 605 uid_t userId = get_user_id(uid); 606 return getUserState(userId); 607} 608 609const UserState* KeyStore::getUserState(uid_t userId) const { 610 for (android::Vector<UserState*>::const_iterator it(mMasterKeys.begin()); 611 it != mMasterKeys.end(); it++) { 612 UserState* state = *it; 613 if (state->getUserId() == userId) { 614 return state; 615 } 616 } 617 618 return NULL; 619} 620 621const UserState* KeyStore::getUserStateByUid(uid_t uid) const { 622 uid_t userId = get_user_id(uid); 623 return getUserState(userId); 624} 625 626bool KeyStore::upgradeBlob(const char* filename, Blob* blob, const uint8_t oldVersion, 627 const BlobType type, uid_t userId) { 628 bool updated = false; 629 uint8_t version = oldVersion; 630 631 /* From V0 -> V1: All old types were unknown */ 632 if (version == 0) { 633 ALOGV("upgrading to version 1 and setting type %d", type); 634 635 blob->setType(type); 636 if (type == TYPE_KEY_PAIR) { 637 importBlobAsKey(blob, filename, userId); 638 } 639 version = 1; 640 updated = true; 641 } 642 643 /* From V1 -> V2: All old keys were encrypted */ 644 if (version == 1) { 645 ALOGV("upgrading to version 2"); 646 647 blob->setEncrypted(true); 648 version = 2; 649 updated = true; 650 } 651 652 /* 653 * If we've updated, set the key blob to the right version 654 * and write it. 655 */ 656 if (updated) { 657 ALOGV("updated and writing file %s", filename); 658 blob->setVersion(version); 659 } 660 661 return updated; 662} 663 664struct BIO_Delete { 665 void operator()(BIO* p) const { BIO_free(p); } 666}; 667typedef std::unique_ptr<BIO, BIO_Delete> Unique_BIO; 668 669ResponseCode KeyStore::importBlobAsKey(Blob* blob, const char* filename, uid_t userId) { 670 // We won't even write to the blob directly with this BIO, so const_cast is okay. 671 Unique_BIO b(BIO_new_mem_buf(const_cast<uint8_t*>(blob->getValue()), blob->getLength())); 672 if (b.get() == NULL) { 673 ALOGE("Problem instantiating BIO"); 674 return ResponseCode::SYSTEM_ERROR; 675 } 676 677 Unique_EVP_PKEY pkey(PEM_read_bio_PrivateKey(b.get(), NULL, NULL, NULL)); 678 if (pkey.get() == NULL) { 679 ALOGE("Couldn't read old PEM file"); 680 return ResponseCode::SYSTEM_ERROR; 681 } 682 683 Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey.get())); 684 int len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), NULL); 685 if (len < 0) { 686 ALOGE("Couldn't measure PKCS#8 length"); 687 return ResponseCode::SYSTEM_ERROR; 688 } 689 690 std::unique_ptr<unsigned char[]> pkcs8key(new unsigned char[len]); 691 uint8_t* tmp = pkcs8key.get(); 692 if (i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp) != len) { 693 ALOGE("Couldn't convert to PKCS#8"); 694 return ResponseCode::SYSTEM_ERROR; 695 } 696 697 ResponseCode rc = importKey(pkcs8key.get(), len, filename, userId, 698 blob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE); 699 if (rc != ResponseCode::NO_ERROR) { 700 return rc; 701 } 702 703 return get(filename, blob, TYPE_KEY_PAIR, userId); 704} 705 706void KeyStore::readMetaData() { 707 int in = TEMP_FAILURE_RETRY(open(sMetaDataFile, O_RDONLY)); 708 if (in < 0) { 709 return; 710 } 711 size_t fileLength = readFully(in, (uint8_t*)&mMetaData, sizeof(mMetaData)); 712 if (fileLength != sizeof(mMetaData)) { 713 ALOGI("Metadata file is %zd bytes (%zd experted); upgrade?", fileLength, sizeof(mMetaData)); 714 } 715 close(in); 716} 717 718void KeyStore::writeMetaData() { 719 const char* tmpFileName = ".metadata.tmp"; 720 int out = 721 TEMP_FAILURE_RETRY(open(tmpFileName, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)); 722 if (out < 0) { 723 ALOGE("couldn't write metadata file: %s", strerror(errno)); 724 return; 725 } 726 size_t fileLength = writeFully(out, (uint8_t*)&mMetaData, sizeof(mMetaData)); 727 if (fileLength != sizeof(mMetaData)) { 728 ALOGI("Could only write %zd bytes to metadata file (%zd expected)", fileLength, 729 sizeof(mMetaData)); 730 } 731 close(out); 732 rename(tmpFileName, sMetaDataFile); 733} 734 735bool KeyStore::upgradeKeystore() { 736 bool upgraded = false; 737 738 if (mMetaData.version == 0) { 739 UserState* userState = getUserStateByUid(0); 740 741 // Initialize first so the directory is made. 742 userState->initialize(); 743 744 // Migrate the old .masterkey file to user 0. 745 if (access(sOldMasterKey, R_OK) == 0) { 746 if (rename(sOldMasterKey, userState->getMasterKeyFileName()) < 0) { 747 ALOGE("couldn't migrate old masterkey: %s", strerror(errno)); 748 return false; 749 } 750 } 751 752 // Initialize again in case we had a key. 753 userState->initialize(); 754 755 // Try to migrate existing keys. 756 DIR* dir = opendir("."); 757 if (!dir) { 758 // Give up now; maybe we can upgrade later. 759 ALOGE("couldn't open keystore's directory; something is wrong"); 760 return false; 761 } 762 763 struct dirent* file; 764 while ((file = readdir(dir)) != NULL) { 765 // We only care about files. 766 if (file->d_type != DT_REG) { 767 continue; 768 } 769 770 // Skip anything that starts with a "." 771 if (file->d_name[0] == '.') { 772 continue; 773 } 774 775 // Find the current file's user. 776 char* end; 777 unsigned long thisUid = strtoul(file->d_name, &end, 10); 778 if (end[0] != '_' || end[1] == 0) { 779 continue; 780 } 781 UserState* otherUser = getUserStateByUid(thisUid); 782 if (otherUser->getUserId() != 0) { 783 unlinkat(dirfd(dir), file->d_name, 0); 784 } 785 786 // Rename the file into user directory. 787 DIR* otherdir = opendir(otherUser->getUserDirName()); 788 if (otherdir == NULL) { 789 ALOGW("couldn't open user directory for rename"); 790 continue; 791 } 792 if (renameat(dirfd(dir), file->d_name, dirfd(otherdir), file->d_name) < 0) { 793 ALOGW("couldn't rename blob: %s: %s", file->d_name, strerror(errno)); 794 } 795 closedir(otherdir); 796 } 797 closedir(dir); 798 799 mMetaData.version = 1; 800 upgraded = true; 801 } 802 803 return upgraded; 804} 805