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

#include <gtest/gtest.h>

#include <errno.h>
#include <keymaster/authorization_set.h>
#include <keymaster/android_keymaster.h>
#include <stdio.h>
#include <time.h>

#include "keymaster_enforcement.h"

namespace keymaster {
namespace test {

class KeymasterBaseTest : public ::testing::Test {
  protected:
    KeymasterBaseTest() {
        past_time = 0;

        time_t t = time(NULL);
        future_tm = localtime(&t);
        future_tm->tm_year += 1;
        future_time = mktime(future_tm);
        sign_param = Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN);
    }
    virtual ~KeymasterBaseTest() {}

    tm past_tm;
    tm* future_tm;
    time_t past_time;
    time_t future_time;
    static const km_id_t key_id = 0xa;
    static const uid_t uid = 0xf;
    keymaster_key_param_t sign_param;
    keymaster_blob_t def_app_id;
    size_t def_app_id_size;

    static const uint32_t valid_user_id = 25;
    static const uint32_t invalid_user_id1 = 37;
    static const uint32_t invalid_user_id2 = 50;
    static const uint32_t appId1 = 51;
    static const uint32_t appId2 = 52;

    static const uint32_t validuid1 =
        valid_user_id * KeymasterEnforcement::MULTIUSER_APP_PER_USER_RANGE +
        (appId1 % KeymasterEnforcement::MULTIUSER_APP_PER_USER_RANGE);
    static const uint32_t validuid2 =
        valid_user_id * KeymasterEnforcement::MULTIUSER_APP_PER_USER_RANGE +
        (appId1 % KeymasterEnforcement::MULTIUSER_APP_PER_USER_RANGE);

    static const uint32_t invaliduid1 =
        invalid_user_id1 * KeymasterEnforcement::MULTIUSER_APP_PER_USER_RANGE +
        (appId1 % KeymasterEnforcement::MULTIUSER_APP_PER_USER_RANGE);
    static const uint32_t invaliduid2 =
        invalid_user_id1 * KeymasterEnforcement::MULTIUSER_APP_PER_USER_RANGE +
        (appId2 % KeymasterEnforcement::MULTIUSER_APP_PER_USER_RANGE);
    static const uint32_t invaliduid3 =
        invalid_user_id2 * KeymasterEnforcement::MULTIUSER_APP_PER_USER_RANGE +
        (appId1 % KeymasterEnforcement::MULTIUSER_APP_PER_USER_RANGE);
    static const uint32_t invaliduid4 =
        invalid_user_id2 * KeymasterEnforcement::MULTIUSER_APP_PER_USER_RANGE +
        (appId2 % KeymasterEnforcement::MULTIUSER_APP_PER_USER_RANGE);
};

TEST_F(KeymasterBaseTest, TEST_VALID_KEY_PERIOD_NO_TAGS) {
    keymaster_key_param_t params[] = {
        sign_param,
    };
    AuthorizationSet single_auth_set(params, 1);
    KeymasterEnforcement kmen;

    keymaster_error_t kmer = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, single_auth_set, uid);
    ASSERT_EQ(KM_ERROR_OK, kmer);
}

TEST_F(KeymasterBaseTest, TEST_INVALID_ACTIVE_TIME) {
    keymaster_key_param_t params[] = {
        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA),
        Authorization(TAG_NO_AUTH_REQUIRED), Authorization(TAG_ACTIVE_DATETIME, future_time),
    };

    KeymasterEnforcement kmen;
    AuthorizationSet auth_set(params, 4);

    keymaster_error_t kmer_invalid_time =
        kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, uid);
    ASSERT_EQ(KM_ERROR_KEY_NOT_YET_VALID, kmer_invalid_time);
}

TEST_F(KeymasterBaseTest, TEST_VALID_ACTIVE_TIME) {
    keymaster_key_param_t params[] = {
        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA),
        Authorization(TAG_ACTIVE_DATETIME, past_time),
    };

    KeymasterEnforcement kmen;
    AuthorizationSet auth_set(params, 3);

    keymaster_error_t kmer_valid_time =
        kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, uid);
    ASSERT_EQ(KM_ERROR_OK, kmer_valid_time);
}

TEST_F(KeymasterBaseTest, TEST_INVALID_ORIGINATION_EXPIRE_TIME) {
    keymaster_key_param_t params[] = {
        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA),
        Authorization(TAG_ACTIVE_DATETIME, past_time),
        Authorization(TAG_ORIGINATION_EXPIRE_DATETIME, past_time),
    };

    KeymasterEnforcement kmen;
    AuthorizationSet auth_set(params, 4);

    keymaster_error_t kmer_invalid_origination =
        kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, uid);
    ASSERT_EQ(KM_ERROR_KEY_EXPIRED, kmer_invalid_origination);
}

TEST_F(KeymasterBaseTest, TEST_VALID_ORIGINATION_EXPIRE_TIME) {
    keymaster_key_param_t params[] = {
        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA),
        Authorization(TAG_ACTIVE_DATETIME, past_time),
        Authorization(TAG_ORIGINATION_EXPIRE_DATETIME, future_time),
    };

    KeymasterEnforcement kmen;
    AuthorizationSet auth_set(params, 4);

    keymaster_error_t kmer_valid_origination =
        kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, uid);
    ASSERT_EQ(KM_ERROR_OK, kmer_valid_origination);
}

TEST_F(KeymasterBaseTest, TEST_INVALID_USAGE_EXPIRE_TIME) {
    keymaster_key_param_t params[] = {
        Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
        Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA),
        Authorization(TAG_ACTIVE_DATETIME, past_time),
        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
        Authorization(TAG_USAGE_EXPIRE_DATETIME, past_time),
    };

    KeymasterEnforcement kmen;
    AuthorizationSet auth_set(params, 5);

    keymaster_error_t kmer_invalid_origination =
        kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set, uid);
    ASSERT_EQ(KM_ERROR_KEY_EXPIRED, kmer_invalid_origination);
}

TEST_F(KeymasterBaseTest, TEST_VALID_USAGE_EXPIRE_TIME) {
    keymaster_key_param_t params[] = {
        Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
        Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA),
        Authorization(TAG_ACTIVE_DATETIME, past_time),
        Authorization(TAG_USAGE_EXPIRE_DATETIME, future_time),
    };

    KeymasterEnforcement kmen;
    AuthorizationSet auth_set(params, 4);

    keymaster_error_t kmer_valid_usage =
        kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set, uid);
    ASSERT_EQ(KM_ERROR_OK, kmer_valid_usage);
}

TEST_F(KeymasterBaseTest, TEST_VALID_SINGLE_USE_ACCESSES) {
    keymaster_key_param_t params[] = {
        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA),
        Authorization(TAG_ACTIVE_DATETIME, past_time),
    };

    KeymasterEnforcement kmen;
    AuthorizationSet auth_set(params, 3);

    keymaster_error_t kmer1 = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, uid);
    keymaster_error_t kmer2 = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, uid);

    ASSERT_EQ(KM_ERROR_OK, kmer1);
    ASSERT_EQ(KM_ERROR_OK, kmer2);
}

TEST_F(KeymasterBaseTest, TEST_INVALID_SINGLE_USE_ACCESSES) {
    keymaster_key_param_t params[] = {
        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA),
        Authorization(TAG_ACTIVE_DATETIME, past_time), Authorization(TAG_MAX_USES_PER_BOOT, 1),
    };

    KeymasterEnforcement kmen;
    AuthorizationSet auth_set(params, 4);

    keymaster_error_t kmer1 = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, uid);
    keymaster_error_t kmer2 = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, uid);

    ASSERT_EQ(KM_ERROR_OK, kmer1);
    ASSERT_EQ(KM_ERROR_TOO_MANY_OPERATIONS, kmer2);
}

TEST_F(KeymasterBaseTest, TEST_INVALID_TIME_BETWEEN_OPS) {
    keymaster_key_param_t params[] = {
        Authorization(TAG_ALL_USERS), Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
        Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA),
        Authorization(TAG_ACTIVE_DATETIME, past_time),
        Authorization(TAG_MIN_SECONDS_BETWEEN_OPS, 10),
    };

    KeymasterEnforcement kmen;
    AuthorizationSet auth_set(params, 5);

    keymaster_error_t kmer1 = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, uid);
    keymaster_error_t kmer2 = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, uid);

    ASSERT_EQ(KM_ERROR_OK, kmer1);
    sleep(2);
    ASSERT_EQ(KM_ERROR_TOO_MANY_OPERATIONS, kmer2);
}

TEST_F(KeymasterBaseTest, TEST_VALID_TIME_BETWEEN_OPS) {
    keymaster_key_param_t params[] = {
        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
        Authorization(TAG_USAGE_EXPIRE_DATETIME, future_time),
        Authorization(TAG_ORIGINATION_EXPIRE_DATETIME, future_time),
        Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA),
        Authorization(TAG_ACTIVE_DATETIME, past_time),
        Authorization(TAG_MIN_SECONDS_BETWEEN_OPS, 2),
    };

    KeymasterEnforcement kmen;
    AuthorizationSet auth_set(params, 7);

    keymaster_error_t kmer1 = kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set, uid);
    sleep(3);
    keymaster_error_t kmer2 = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, uid);

    ASSERT_EQ(KM_ERROR_OK, kmer1);
    ASSERT_EQ(KM_ERROR_OK, kmer2);
}

TEST_F(KeymasterBaseTest, TEST_USER_ID) {
    keymaster_key_param_t params[] = {
        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_USER_ID, valid_user_id),
    };

    KeymasterEnforcement kmen;
    AuthorizationSet auth_set(params, 2);

    keymaster_error_t valid_kmer1 =
        kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, validuid1);
    keymaster_error_t valid_kmer2 =
        kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, validuid2);

    keymaster_error_t invalid_kmer1 =
        kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, invaliduid1);
    keymaster_error_t invalid_kmer2 =
        kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, invaliduid2);
    keymaster_error_t invalid_kmer3 =
        kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, invaliduid3);
    keymaster_error_t invalid_kmer4 =
        kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, invaliduid4);

    ASSERT_EQ(KM_ERROR_OK, valid_kmer1);
    ASSERT_EQ(KM_ERROR_OK, valid_kmer2);

    ASSERT_EQ(KM_ERROR_INVALID_USER_ID, invalid_kmer1);
    ASSERT_EQ(KM_ERROR_INVALID_USER_ID, invalid_kmer2);
    ASSERT_EQ(KM_ERROR_INVALID_USER_ID, invalid_kmer3);
    ASSERT_EQ(KM_ERROR_INVALID_USER_ID, invalid_kmer4);
}

TEST_F(KeymasterBaseTest, TEST_INVALID_PURPOSE) {
    keymaster_purpose_t invalidPurpose1 = static_cast<keymaster_purpose_t>(-1);
    keymaster_purpose_t invalidPurpose2 = static_cast<keymaster_purpose_t>(4);

    keymaster_key_param_t params1[] = {
        Authorization(TAG_PURPOSE, invalidPurpose1), Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA),
        Authorization(TAG_ACTIVE_DATETIME, past_time),
    };

    keymaster_key_param_t params2[] = {
        Authorization(TAG_PURPOSE, invalidPurpose2), Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA),
        Authorization(TAG_ACTIVE_DATETIME, past_time),
    };

    KeymasterEnforcement kmen;
    AuthorizationSet auth_set1(params1, 3);
    AuthorizationSet auth_set2(params2, 3);

    keymaster_error_t kmer1 = kmen.AuthorizeOperation(invalidPurpose1, key_id, auth_set1, uid);
    keymaster_error_t kmer2 = kmen.AuthorizeOperation(invalidPurpose2, key_id, auth_set2, uid);
    keymaster_error_t kmer3 = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set2, uid);

    ASSERT_EQ(KM_ERROR_UNSUPPORTED_PURPOSE, kmer1);
    ASSERT_EQ(KM_ERROR_UNSUPPORTED_PURPOSE, kmer2);
    ASSERT_EQ(KM_ERROR_UNSUPPORTED_PURPOSE, kmer3);
}

TEST_F(KeymasterBaseTest, TEST_INCOMPATIBLE_PURPOSE) {
    keymaster_key_param_t params[] = {
        Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
        Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA),
        Authorization(TAG_ACTIVE_DATETIME, past_time), Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
    };
    KeymasterEnforcement kmen;
    AuthorizationSet auth_set(params, 4);

    keymaster_error_t kmer_invalid1 =
        kmen.AuthorizeOperation(KM_PURPOSE_ENCRYPT, key_id, auth_set, uid);
    keymaster_error_t kmer_invalid2 =
        kmen.AuthorizeOperation(KM_PURPOSE_DECRYPT, key_id, auth_set, uid);

    keymaster_error_t kmer_valid1 = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, uid);
    keymaster_error_t kmer_valid2 =
        kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set, uid);

    ASSERT_EQ(KM_ERROR_OK, kmer_valid1);
    ASSERT_EQ(KM_ERROR_OK, kmer_valid2);
    ASSERT_EQ(KM_ERROR_INCOMPATIBLE_PURPOSE, kmer_invalid1);
    ASSERT_EQ(KM_ERROR_INCOMPATIBLE_PURPOSE, kmer_invalid2);
}

TEST_F(KeymasterBaseTest, TEST_INVALID_TAG_PAIRS) {
    const uint8_t* app_id = reinterpret_cast<const uint8_t*>("com.app");
    const size_t app_size = 7;
    keymaster_key_param_t params1[] = {
        Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
        Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA),
        Authorization(TAG_ACTIVE_DATETIME, past_time), Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
        // Can't have "all users" and a specific user.
        Authorization(TAG_ALL_USERS), Authorization(TAG_USER_ID, valid_user_id),
    };

    keymaster_key_param_t params2[] = {
        Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
        Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA),
        Authorization(TAG_ACTIVE_DATETIME, past_time), Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
        // Can't have "all applications" and a specific app ID.
        Authorization(TAG_ALL_APPLICATIONS), Authorization(TAG_APPLICATION_ID, app_id, app_size),
    };

    KeymasterEnforcement kmen;
    AuthorizationSet auth_set1(params1, array_length(params1));
    AuthorizationSet auth_set2(params2, array_length(params2));

    EXPECT_EQ(KM_ERROR_INVALID_TAG,
              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set1, validuid1));
    EXPECT_EQ(KM_ERROR_INVALID_TAG,
              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set2, validuid1));
}

}; /* namespace test */
}; /* namespace keymaster */
