/*
 * 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.
 */

#ifndef ANDROID_LIBRARY_KEYMASTER_ENFORCEMENT_H
#define ANDROID_LIBRARY_KEYMASTER_ENFORCEMENT_H

#include <stdio.h>

#include <utils/List.h>

#include <keymaster/authorization_set.h>

using namespace android;

typedef uint32_t km_id_t;

namespace keymaster {

struct access_time_struct {
    uint32_t keyid;
    time_t access_time;
};

class KeymasterEnforcement {

  public:
    KeymasterEnforcement();

    ~KeymasterEnforcement();

    /**
     * Iterates through the authorization set and returns the corresponding keymaster error. Will
     * return KM_ERROR_OK if all criteria is met for the given purpose in the authorization
     * set. Used for encrypt, decrypt sign, and verify.
     */
    keymaster_error_t AuthorizeOperation(const keymaster_purpose_t purpose, const km_id_t keyid,
                                         const AuthorizationSet& auth_set, const uid_t uid);

    /**
     * This is maintained in system/core/include/cutiles/multiuser.h but copied here so that this
     * code can be reused without access to the core Android libs.
     */
    static const uint32_t MULTIUSER_APP_PER_USER_RANGE = 100000;

  private:
    /*
     * Handles the KM_TAG_ACTIVE_DATETIME tag.  Returns KM_ERROR_OK if currentTime is greater than
     * the the time value associated with param.
     */
    keymaster_error_t Active(const keymaster_key_param_t param, const time_t current_time);

    /*
     * Handles the KM_TAG_USAGE_EXPIRE_DATETIME tag.  Returns KM_ERROR_OK if currentTime is less
     * than the time value associated with param and if purpose is KM_PURPOSE_VERIFY.  If purpose is
     * not KM_PURPOSE_VERIFY will return KM_ERROR_OK.
     */
    keymaster_error_t UsageNotExpired(const keymaster_key_param_t param, const time_t current_time,
                                      const keymaster_purpose_t purpose);

    /*
     * Handles the KM_TAG_ORIGINATION_EXPIRE_TIME tag.  Returns KM_ERROR_OK if currentTime is less
     * than the time value associated with param and if purpose is KM_PURPOSE_SIGN.  If purpose is
     * not KM_PURPOSE_SIGN will return KM_ERROR_OK.
     */
    keymaster_error_t OriginationNotExpired(const keymaster_key_param_t param,
                                            const time_t current_time,
                                            const keymaster_purpose_t purpose);

    /*
     * Handles the KM_TAG_MIN_SECONDS_BETWEEN_OPS tag.  Returns KM_ERROR_OK if the difference
     * between currentTime and the last accessed time for the keyid is less than the time value
     * associated with param.
     */
    keymaster_error_t MinTimeBetweenOpsPassed(const keymaster_key_param_t param,
                                              const km_id_t keyid, const time_t current_time);

    /*
     * Handles the KM_TAG_SINGLE_USE_PER_BOOT tag.  Returns KM_ERROR_OK if the keyid's last accessed
     * time is -1 (has not been accessed).
     */
    keymaster_error_t NotUsedSinceBoot(const km_id_t keyid);

    /*
     * Handles the KM_TAG_USER_ID tag.  Returns KM_ERROR_OK if the integer value of the parameter is
     * equal to the appId derived from the uid.
     */
    keymaster_error_t UserAuthenticated(const keymaster_key_param_t param, const uid_t uid);

    /*
     * Handles KM_TAG_AUTH_TIMEOUT tags.  Returns KM_ERROR_OK if the last time the user
     * authenticated is within the required freshness.
     */
    keymaster_error_t AuthenticationIsFresh(const keymaster_key_param_t param,
                                            const time_t current_time) const;

    /*
     * Updates the most recent user authentication time to the current time.
     */
    void UpdateUserAuthenticationTime();

    /*
     * Class to abstract the mechanism used to keep track of access times.
     */
    class AccessTimeMap {
      public:
        AccessTimeMap();

        /* Returns the last time the key was accessed. */
        time_t last_key_access_time(uint32_t index);

        /* Updates the last key access time with the currentTime parameter. */
        void update_key_access_time(uint32_t index, time_t current_time);

      private:
        /**
         * Internal datastructure that maps keyid to access time. Can be
         * replaced with the cutil hashmap, linked list, etc.
         */
        List<access_time_struct> last_access_list;

        /* Returns an iterator to the node with the keyid or end if not found. */
        List<access_time_struct>::iterator find(uint32_t keyid);
    };

    /*
     * Tests if the purpose is a valid member of keymaster_purpose_t and if the purpose is among
     * those listed in the AuthorizationSet and returns KM_ERROR_OK if so and an appropriate error
     * otherwise.
     */
    keymaster_error_t valid_purpose(const keymaster_purpose_t purpose,
                                    const AuthorizationSet& auth_set);

    /*
     * Tests that all of the purposes in the authorization set are valid. Returns KM_ERROR_OK if so
     * and KM_ERROR_UNSUPPORTED_PURPOSE otherwise.
     */
    bool supported_purposes(const AuthorizationSet& auth_set);

    /*
     * Returns true if the purpose is among supported purposes and false otherwise.
     */
    bool supported_purpose(const keymaster_purpose_t purpose);

    /*
     * Abstraction that currently just returns time(NULL).  TODO: time() is a no-op in trusty. Still
     * need to handle this.
     */
    time_t get_current_time() const;

    /*
     * Updates the last time that the key was accessed to the current time.
     */
    void update_key_access_time(const km_id_t keyid);

    /*
     * Returns the last time that the key was accessed.
     */
    time_t get_last_access_time(const km_id_t keyid);

    /*
     * Generates the userId from the uid using the formula
     * userId = uid / MULTIUSER_APP_PER_USER_RAGE.
     */
    static uint32_t get_user_id_from_uid(const uid_t uid);

    /* Returns the last time that the user authenticated. */
    time_t get_last_auth_time() const;

    /*
     * Returns KM_ERROR_KEY_EXPIRED if the difference between the current time and the parameters's
     * date_time field is positive.
     */
    keymaster_error_t is_time_expired(const keymaster_key_param_t param, const time_t current_time);

    /* Hashmap of last access times. */
    AccessTimeMap accessTimeMap;

    /* The time of the most recent user authentication. */
    time_t last_auth_time;
};
}; /* namespace keymaster */

#endif  // ANDROID_LIBRARY_KEYMASTER_ENFORCEMENT_H
