/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "keystore"

#include "KeyStore.h"

#include <dirent.h>
#include <fcntl.h>

#include <openssl/bio.h>

#include <utils/String16.h>
#include <utils/String8.h>

#include <android-base/scopeguard.h>
#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
#include <android/security/keystore/IKeystoreService.h>
#include <log/log_event_list.h>

#include <private/android_logger.h>

#include "keystore_utils.h"
#include "permissions.h"
#include <keystore/keystore_hidl_support.h>

#include "keymaster_worker.h"

namespace keystore {

const char* KeyStore::kOldMasterKey = ".masterkey";
const char* KeyStore::kMetaDataFile = ".metadata";

const android::String16 KeyStore::kRsaKeyType("RSA");
const android::String16 KeyStore::kEcKeyType("EC");

using android::String8;

KeyStore::KeyStore(const KeymasterDevices& kmDevices,
                   SecurityLevel minimalAllowedSecurityLevelForNewKeys)
    : mAllowNewFallback(minimalAllowedSecurityLevelForNewKeys == SecurityLevel::SOFTWARE),
      mConfirmationManager(new ConfirmationManager(this)) {
    memset(&mMetaData, '\0', sizeof(mMetaData));

    static_assert(std::tuple_size<std::decay_t<decltype(kmDevices)>>::value ==
                      std::tuple_size<decltype(mKmDevices)>::value,
                  "KmasterDevices and KeymasterWorkers must have the same size");
    for (size_t i = 0; i < kmDevices.size(); ++i) {
        if (kmDevices[SecurityLevel(i)]) {
            mKmDevices[SecurityLevel(i)] =
                std::make_shared<KeymasterWorker>(kmDevices[SecurityLevel(i)], this);
        }
    }
}

KeyStore::~KeyStore() {
}

ResponseCode KeyStore::initialize() {
    readMetaData();
    if (upgradeKeystore()) {
        writeMetaData();
    }

    return ResponseCode::NO_ERROR;
}

ResponseCode KeyStore::initializeUser(const android::String8& pw, uid_t userId) {
    auto userState = mUserStateDB.getUserState(userId);
    return userState->initialize(pw);
}

ResponseCode KeyStore::copyMasterKey(uid_t srcUser, uid_t dstUser) {
    auto userState = mUserStateDB.getUserState(dstUser);
    auto initState = mUserStateDB.getUserState(srcUser);
    return userState->copyMasterKey(&initState);
}

ResponseCode KeyStore::writeMasterKey(const android::String8& pw, uid_t userId) {
    auto userState = mUserStateDB.getUserState(userId);
    return userState->writeMasterKey(pw);
}

ResponseCode KeyStore::readMasterKey(const android::String8& pw, uid_t userId) {
    auto userState = mUserStateDB.getUserState(userId);
    return userState->readMasterKey(pw);
}

LockedKeyBlobEntry KeyStore::getLockedBlobEntryIfNotExists(const std::string& alias, uid_t uid) {
    KeyBlobEntry kbe(alias, mUserStateDB.getUserStateByUid(uid)->getUserDirName(), uid);
    auto result = LockedKeyBlobEntry::get(std::move(kbe));
    if (result->hasKeyBlob()) return {};
    return result;
}

std::optional<KeyBlobEntry> KeyStore::getBlobEntryIfExists(const std::string& alias, uid_t uid) {
    KeyBlobEntry kbe(alias, mUserStateDB.getUserStateByUid(uid)->getUserDirName(), uid);
    if (kbe.hasKeyBlob()) return kbe;

    // If this is one of the legacy UID->UID mappings, use it.
    uid_t euid = get_keystore_euid(uid);
    if (euid != uid) {
        kbe = KeyBlobEntry(alias, mUserStateDB.getUserStateByUid(euid)->getUserDirName(), euid);
        if (kbe.hasKeyBlob()) return kbe;
    }

    // They might be using a granted key.
    auto grant = mGrants.get(uid, alias);
    if (grant) {
        kbe = grant->entry_;
        if (kbe.hasKeyBlob()) return kbe;
    }
    return {};
}
LockedKeyBlobEntry KeyStore::getLockedBlobEntryIfExists(const std::string& alias, uid_t uid) {
    auto blobentry = getBlobEntryIfExists(alias, uid);
    if (!blobentry) return {};
    LockedKeyBlobEntry lockedentry = LockedKeyBlobEntry::get(std::move(*blobentry));
    if (!lockedentry || !lockedentry->hasKeyBlob()) return {};
    return lockedentry;
}

void KeyStore::resetUser(uid_t userId, bool keepUnenryptedEntries) {
    android::String8 prefix("");
    android::Vector<android::String16> aliases;

    auto userState = mUserStateDB.getUserState(userId);
    std::string userDirName = userState->getUserDirName();
    auto encryptionKey = userState->getEncryptionKey();
    auto state = userState->getState();
    // userState is a proxy that holds a lock which may be required by a worker.
    // LockedKeyBlobEntry::list has a fence that waits until all workers have finished which may
    // not happen if a user state lock is held. The following line relinquishes the lock.
    userState = {};

    ResponseCode rc;
    std::list<LockedKeyBlobEntry> matches;

    // must not be called by a keymaster worker. List waits for workers to relinquish all access
    // to blob entries
    std::tie(rc, matches) = LockedKeyBlobEntry::list(userDirName);
    if (rc != ResponseCode::NO_ERROR) {
        return;
    }

    for (LockedKeyBlobEntry& lockedEntry : matches) {
        bool shouldDelete = true;

        if (keepUnenryptedEntries) {
            Blob blob;
            Blob charBlob;
            ResponseCode rc;

            std::tie(rc, blob, charBlob) = lockedEntry.readBlobs(encryptionKey, state);

            switch (rc) {
            case ResponseCode::SYSTEM_ERROR:
            case ResponseCode::VALUE_CORRUPTED:
                // If we can't read blobs, delete them.
                shouldDelete = true;
                break;

            case ResponseCode::NO_ERROR:
            case ResponseCode::LOCKED:
                // Delete encrypted blobs but keep unencrypted blobs and super-encrypted blobs.  We
                // need to keep super-encrypted blobs so we can report that the user is
                // unauthenticated if a caller tries to use them, rather than reporting that they
                // don't exist.
                shouldDelete = blob.isEncrypted();
                break;

            default:
                ALOGE("Got unexpected return code %d from readBlobs", rc);
                // This shouldn't happen.  To be on the safe side, delete it.
                shouldDelete = true;
                break;
            }
        }
        if (shouldDelete) {
            del(lockedEntry);
        }
    }

    userState = mUserStateDB.getUserState(userId);
    if (!userState->deleteMasterKey()) {
        ALOGE("Failed to delete user %d's master key", userId);
    }
    if (!keepUnenryptedEntries) {
        if (!userState->reset()) {
            ALOGE("Failed to remove user %d's directory", userId);
        }
    }
}

bool KeyStore::isEmpty(uid_t userId) const {
    std::string userDirName;
    {
        // userState holds a lock which must be relinquished before list is called. This scope
        // prevents deadlocks.
        auto userState = mUserStateDB.getUserState(userId);
        if (!userState) {
            return true;
        }
        userDirName = userState->getUserDirName();
    }

    ResponseCode rc;
    std::list<LockedKeyBlobEntry> matches;

    // must not be called by a keymaster worker. List waits for workers to relinquish all access
    // to blob entries
    std::tie(rc, matches) = LockedKeyBlobEntry::list(userDirName);

    return rc == ResponseCode::SYSTEM_ERROR || matches.size() == 0;
}

void KeyStore::lock(uid_t userId) {
    auto userState = mUserStateDB.getUserState(userId);
    userState->zeroizeMasterKeysInMemory();
    userState->setState(STATE_LOCKED);
}

static void maybeLogKeyIntegrityViolation(const LockedKeyBlobEntry& lockedEntry,
                                          const BlobType type) {
    if (!__android_log_security() || (type != TYPE_KEY_PAIR && type != TYPE_KEYMASTER_10)) return;
    log_key_integrity_violation(lockedEntry->alias().c_str(), lockedEntry->uid());
}

std::tuple<ResponseCode, Blob, Blob> KeyStore::get(const LockedKeyBlobEntry& blobfile) {
    std::tuple<ResponseCode, Blob, Blob> result;

    uid_t userId = get_user_id(blobfile->uid());
    Blob& keyBlob = std::get<1>(result);
    ResponseCode& rc = std::get<0>(result);

    auto userState = mUserStateDB.getUserState(userId);
    BlobType type = BlobType::TYPE_ANY;
    auto logOnScopeExit = android::base::make_scope_guard([&] {
        if (rc == ResponseCode::VALUE_CORRUPTED) {
            maybeLogKeyIntegrityViolation(blobfile, type);
        }
    });

    result = blobfile.readBlobs(userState->getEncryptionKey(), userState->getState());
    if (rc != ResponseCode::NO_ERROR) {
        return result;
    }

    // update the type for logging (see scope_guard above)
    type = keyBlob.getType();

    const uint8_t version = keyBlob.getVersion();
    if (version < CURRENT_BLOB_VERSION) {
        /* If we upgrade the key, we need to write it to disk again. Then
         * it must be read it again since the blob is encrypted each time
         * it's written.
         */
        if (upgradeBlob(&keyBlob, version)) {
            if ((rc = this->put(blobfile, keyBlob, {})) != ResponseCode::NO_ERROR ||
                (result = blobfile.readBlobs(userState->getEncryptionKey(), userState->getState()),
                 rc) != ResponseCode::NO_ERROR) {
                return result;
            }
        }
    }

    return result;
}

ResponseCode KeyStore::put(const LockedKeyBlobEntry& blobfile, Blob keyBlob,
                           Blob characteristicsBlob) {
    auto userState = mUserStateDB.getUserStateByUid(blobfile->uid());
    return blobfile.writeBlobs(std::move(keyBlob), std::move(characteristicsBlob),
                               userState->getEncryptionKey(), userState->getState());
}

ResponseCode KeyStore::del(const LockedKeyBlobEntry& blobfile) {
    Blob keyBlob;
    Blob charactaristicsBlob;
    ResponseCode rc;
    uid_t uid = blobfile->uid();
    std::string alias = blobfile->alias();

    std::tie(rc, keyBlob, charactaristicsBlob) = get(blobfile);

    // after getting the blob from the file system we scrub the filesystem.
    mGrants.removeAllGrantsToKey(uid, alias);
    auto result = blobfile.deleteBlobs();

    if (rc != ResponseCode::NO_ERROR) {
        LOG(ERROR) << "get keyblob failed " << int(rc);
        return rc;
    }

    // if we got the blob successfully, we try and delete it from the keymaster device
    auto dev = getDevice(keyBlob);

    if (keyBlob.getType() == ::TYPE_KEYMASTER_10) {
        dev->deleteKey(blob2hidlVec(keyBlob), [dev, alias, uid](Return<ErrorCode> rc) {
            auto ret = KS_HANDLE_HIDL_ERROR(dev, rc);
            // A device doesn't have to implement delete_key.
            bool success = ret == ErrorCode::OK || ret == ErrorCode::UNIMPLEMENTED;
            if (__android_log_security()) {
                android_log_event_list(SEC_TAG_KEY_DESTROYED)
                    << int32_t(success) << alias << int32_t(uid) << LOG_ID_SECURITY;
            }
            if (!success) {
                LOG(ERROR) << "Keymaster delete for key " << alias << " of uid " << uid
                           << " failed";
            }
        });
    }

    return result;
}

std::string KeyStore::addGrant(const LockedKeyBlobEntry& blobfile, uid_t granteeUid) {
    return mGrants.put(granteeUid, blobfile);
}

bool KeyStore::removeGrant(const LockedKeyBlobEntry& blobfile, const uid_t granteeUid) {
    return mGrants.removeByFileAlias(granteeUid, blobfile);
}
void KeyStore::removeAllGrantsToUid(const uid_t granteeUid) {
    mGrants.removeAllGrantsToUid(granteeUid);
}

bool KeyStore::isHardwareBacked(const android::String16& keyType) const {
    // if strongbox device is present TEE must also be present and of sufficiently high version
    // to support all keys in hardware
    if (getDevice(SecurityLevel::STRONGBOX)) return true;
    if (!getDevice(SecurityLevel::TRUSTED_ENVIRONMENT)) {
        ALOGW("can't get keymaster device");
        return false;
    }

    auto version = getDevice(SecurityLevel::TRUSTED_ENVIRONMENT)->halVersion();
    if (keyType == kRsaKeyType) return true;  // All versions support RSA
    return keyType == kEcKeyType && version.supportsEc;
}

std::tuple<ResponseCode, Blob, Blob, LockedKeyBlobEntry>
KeyStore::getKeyForName(const android::String8& keyName, const uid_t uid, const BlobType type) {
    std::tuple<ResponseCode, Blob, Blob, LockedKeyBlobEntry> result;
    auto& [rc, keyBlob, charBlob, lockedEntry] = result;

    lockedEntry = getLockedBlobEntryIfExists(keyName.string(), uid);

    if (!lockedEntry) return rc = ResponseCode::KEY_NOT_FOUND, std::move(result);

    std::tie(rc, keyBlob, charBlob) = get(lockedEntry);

    if (rc == ResponseCode::NO_ERROR) {
        if (keyBlob.getType() != type) return rc = ResponseCode::KEY_NOT_FOUND, std::move(result);
    }
    return result;
}

bool KeyStore::upgradeBlob(Blob* blob, const uint8_t oldVersion) {
    bool updated = false;
    uint8_t version = oldVersion;

    if (!blob || !(*blob)) return false;

    /* From V0 -> V1: All old types were unknown */
    if (version == 0) {
        ALOGE("Failed to upgrade key blob. Ancient blob version 0 is no longer supported");

        return false;
    }

    /* From V1 -> V2: All old keys were encrypted */
    if (version == 1) {
        ALOGV("upgrading to version 2");

        blob->setEncrypted(true);
        version = 2;
        updated = true;
    }

    /*
     * If we've updated, set the key blob to the right version
     * and write it.
     */
    if (updated) {
        blob->setVersion(version);
    }

    return updated;
}

void KeyStore::readMetaData() {
    int in = TEMP_FAILURE_RETRY(open(kMetaDataFile, O_RDONLY));
    if (in < 0) {
        return;
    }
    size_t fileLength = readFully(in, (uint8_t*)&mMetaData, sizeof(mMetaData));
    if (fileLength != sizeof(mMetaData)) {
        ALOGI("Metadata file is %zd bytes (%zd experted); upgrade?", fileLength, sizeof(mMetaData));
    }
    close(in);
}

void KeyStore::writeMetaData() {
    const char* tmpFileName = ".metadata.tmp";
    int out =
        TEMP_FAILURE_RETRY(open(tmpFileName, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR));
    if (out < 0) {
        ALOGE("couldn't write metadata file: %s", strerror(errno));
        return;
    }
    size_t fileLength = writeFully(out, (uint8_t*)&mMetaData, sizeof(mMetaData));
    if (fileLength != sizeof(mMetaData)) {
        ALOGI("Could only write %zd bytes to metadata file (%zd expected)", fileLength,
              sizeof(mMetaData));
    }
    close(out);
    rename(tmpFileName, kMetaDataFile);
}

bool KeyStore::upgradeKeystore() {
    bool upgraded = false;

    if (mMetaData.version == 0) {
        auto userState = getUserStateDB().getUserStateByUid(0);

        // Initialize first so the directory is made.
        userState->initialize();

        // Migrate the old .masterkey file to user 0.
        if (access(kOldMasterKey, R_OK) == 0) {
            if (rename(kOldMasterKey, userState->getMasterKeyFileName().c_str()) < 0) {
                ALOGE("couldn't migrate old masterkey: %s", strerror(errno));
                return false;
            }
        }

        // Initialize again in case we had a key.
        userState->initialize();

        // Try to migrate existing keys.
        DIR* dir = opendir(".");
        if (!dir) {
            // Give up now; maybe we can upgrade later.
            ALOGE("couldn't open keystore's directory; something is wrong");
            return false;
        }

        struct dirent* file;
        while ((file = readdir(dir)) != nullptr) {
            // We only care about files.
            if (file->d_type != DT_REG) {
                continue;
            }

            // Skip anything that starts with a "."
            if (file->d_name[0] == '.') {
                continue;
            }

            // Find the current file's user.
            char* end;
            unsigned long thisUid = strtoul(file->d_name, &end, 10);
            if (end[0] != '_' || end[1] == 0) {
                continue;
            }
            auto otherUser = getUserStateDB().getUserStateByUid(thisUid);
            if (otherUser->getUserId() != 0) {
                unlinkat(dirfd(dir), file->d_name, 0);
            }

            // Rename the file into user directory.
            DIR* otherdir = opendir(otherUser->getUserDirName().c_str());
            if (otherdir == nullptr) {
                ALOGW("couldn't open user directory for rename");
                continue;
            }
            if (renameat(dirfd(dir), file->d_name, dirfd(otherdir), file->d_name) < 0) {
                ALOGW("couldn't rename blob: %s: %s", file->d_name, strerror(errno));
            }
            closedir(otherdir);
        }
        closedir(dir);

        mMetaData.version = 1;
        upgraded = true;
    }

    return upgraded;
}

void KeyStore::binderDied(const ::android::wp<IBinder>& who) {
    for (unsigned i = 0; i < mKmDevices.size(); ++i) {
        if (mKmDevices[SecurityLevel(i)]) mKmDevices[SecurityLevel(i)]->binderDied(who);
    }
    getConfirmationManager().binderDied(who);
}

}  // namespace keystore
