/*
 * Copyright (C) 2017 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.
 */

package com.android.server.locksettings.recoverablekeystore.storage;

import static android.security.keystore.recovery.RecoveryController.ERROR_SERVICE_INTERNAL_ERROR;

import android.annotation.Nullable;
import android.os.ServiceSpecificException;
import android.security.KeyStore2;
import android.security.keystore.KeyProperties;
import android.security.keystore.KeyProtection;
import android.system.keystore2.Domain;
import android.system.keystore2.KeyDescriptor;
import android.system.keystore2.KeyPermission;
import android.util.Log;

import com.android.internal.annotations.VisibleForTesting;
import com.android.server.locksettings.recoverablekeystore.KeyStoreProxy;
import com.android.server.locksettings.recoverablekeystore.KeyStoreProxyImpl;

import java.security.KeyStore.SecretKeyEntry;
import java.security.KeyStoreException;
import java.util.Locale;

import javax.crypto.spec.SecretKeySpec;

/**
 * Storage for Application keys in LockSettings service KeyStore namespace.
 *
 * <p> Uses KeyStore's grant mechanism to make keys usable by application process without
 * revealing key material
 */
public class ApplicationKeyStorage {
    private static final String TAG = "RecoverableAppKeyStore";

    private static final String APPLICATION_KEY_ALIAS_PREFIX =
            "com.android.server.locksettings.recoverablekeystore/application/";
    private static final String APPLICATION_KEY_GRANT_PREFIX = "recoverable_key:";

    private final KeyStoreProxy mKeyStore;

    /**
     * Creates a new instance.
     */
    public static ApplicationKeyStorage getInstance()
            throws KeyStoreException {
        return new ApplicationKeyStorage(
                new KeyStoreProxyImpl(KeyStoreProxyImpl.getAndLoadAndroidKeyStore()));
    }

    @VisibleForTesting
    ApplicationKeyStorage(KeyStoreProxy keyStore) {
        mKeyStore = keyStore;
    }

    /**
     * Returns String representation of {@code KeyDescriptor} valid in application's namespace.
     */
    public @Nullable String getGrantAlias(int userId, int uid, String alias) {
        Log.i(TAG, String.format(Locale.US, "Get %d/%d/%s", userId, uid, alias));
        String keystoreAlias = getInternalAlias(userId, uid, alias);
        return makeKeystoreEngineGrantString(uid, keystoreAlias);
    }

    public void setSymmetricKeyEntry(int userId, int uid, String alias, byte[] secretKey)
            throws KeyStoreException {
        Log.i(TAG, String.format(Locale.US, "Set %d/%d/%s: %d bytes of key material",
                userId, uid, alias, secretKey.length));
        try {
            mKeyStore.setEntry(
                getInternalAlias(userId, uid, alias),
                new SecretKeyEntry(
                    new SecretKeySpec(secretKey, KeyProperties.KEY_ALGORITHM_AES)),
                new KeyProtection.Builder(
                        KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
                    .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
                    .build());
        } catch (KeyStoreException e) {
            throw new ServiceSpecificException(ERROR_SERVICE_INTERNAL_ERROR, e.getMessage());
        }
    }

    public void deleteEntry(int userId, int uid, String alias) {
        Log.i(TAG, String.format(Locale.US, "Del %d/%d/%s", userId, uid, alias));
        try {
            mKeyStore.deleteEntry(getInternalAlias(userId, uid, alias));
        } catch (KeyStoreException e) {
            throw new ServiceSpecificException(ERROR_SERVICE_INTERNAL_ERROR, e.getMessage());
        }
    }

    /**
     * Returns the alias in locksettins service's KeyStore namespace used for given application key.
     *
     * <p>These IDs look as follows:
     * {@code com.security.recoverablekeystore/application/<userId>/<uid>/<alias>}
     *
     * @param userId The ID of the user
     * @param uid The uid
     * @param alias - alias in application's namespace
     * @return The alias.
     */
    private String getInternalAlias(int userId, int uid, String alias) {
        return APPLICATION_KEY_ALIAS_PREFIX + userId + "/" + uid + "/" + alias;
    }

    private String makeKeystoreEngineGrantString(int uid, String alias) {
        if (alias == null) {
            return null;
        }

        KeyDescriptor key = new KeyDescriptor();
        key.domain = Domain.APP;
        key.nspace = KeyProperties.NAMESPACE_APPLICATION;
        key.alias = alias;
        key.blob = null;

        int grantAccessVector = KeyPermission.USE | KeyPermission.GET_INFO | KeyPermission.DELETE;

        try {
            key = KeyStore2.getInstance().grant(key, uid, grantAccessVector);
        } catch (android.security.KeyStoreException e) {
            Log.e(TAG, "Failed to get grant for KeyStore key.", e);
            throw new ServiceSpecificException(ERROR_SERVICE_INTERNAL_ERROR, e.getMessage());
        }
        return String.format("%s%016X", APPLICATION_KEY_GRANT_PREFIX, key.nspace);
    }
}
