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