// ----------------------------------------------------------------------------
// Copyright 2016-2017 ARM Ltd.
//  
// 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 "factory_configurator_client.h"
#include "fcc_status.h"
#include "fcc_utils.h"
#include "key_config_manager.h"
#include "pv_error_handling.h"
#include "fcc_sotp.h"


const char g_sotp_entropy_data_type_name[] = "EntropyData";
const char g_sotp_rot_data_type_name[] = "ROTData";
const char g_sotp_factory_disable_type_name[] = "FactoryDisableFlag";
const char g_sotp_ca_server_id_type_name[] = "CAServerId";
const char g_sotp_time_type_name[] = "Time";
const char g_sotp_wrong_type_name[] = "Wrong_sotp_type";


fcc_status_e fcc_get_sotp_type_name(sotp_type_e sotp_type,char **sotp_type_name, size_t *sotp_type_name_size)
{

    fcc_status_e fcc_status = FCC_STATUS_SUCCESS;

    SA_PV_ERR_RECOVERABLE_RETURN_IF((sotp_type_name_size == NULL), fcc_status, "Wrong sotp_type_name_size pointer");

    switch (sotp_type) {
    case SOTP_TYPE_ROT:
        *sotp_type_name = (char*)g_sotp_rot_data_type_name;
        *sotp_type_name_size = (size_t)strlen(g_sotp_rot_data_type_name);
        break;
    case SOTP_TYPE_FACTORY_DONE:
        *sotp_type_name = (char*)g_sotp_factory_disable_type_name;
        *sotp_type_name_size = (size_t)strlen(g_sotp_factory_disable_type_name);
        break;
    case SOTP_TYPE_RANDOM_SEED:
        *sotp_type_name = (char*)g_sotp_entropy_data_type_name;
        *sotp_type_name_size = (size_t)strlen(g_sotp_entropy_data_type_name);
        break;
    case SOTP_TYPE_SAVED_TIME:
        *sotp_type_name = (char*)g_sotp_time_type_name;
        *sotp_type_name_size = (size_t)strlen(g_sotp_time_type_name);
        break;
    case SOTP_TYPE_TRUSTED_TIME_SRV_ID:
        *sotp_type_name = (char*)g_sotp_ca_server_id_type_name;
        *sotp_type_name_size = (size_t)strlen(g_sotp_ca_server_id_type_name);
        break;
    default:
        SA_PV_LOG_ERR("Non existent sotp_type provided");
        *sotp_type_name = (char*)g_sotp_wrong_type_name;
        *sotp_type_name_size = (size_t)strlen(g_sotp_wrong_type_name);
        return FCC_STATUS_INVALID_PARAMETER;
    }

    return fcc_status;
}

fcc_status_e fcc_convert_kcm_to_fcc_status(kcm_status_e kcm_result)
{
    fcc_status_e fcc_status = FCC_STATUS_SUCCESS;

    switch (kcm_result) {
        case (KCM_STATUS_SUCCESS):
            fcc_status = FCC_STATUS_SUCCESS;
            break;
        case (KCM_STATUS_ERROR):
        case (KCM_STATUS_INVALID_PARAMETER):
        case (KCM_STATUS_OUT_OF_MEMORY):
        case (KCM_STATUS_INSUFFICIENT_BUFFER):
            fcc_status = FCC_STATUS_KCM_ERROR;
            break;
        case (KCM_STATUS_ITEM_NOT_FOUND):
            fcc_status = FCC_STATUS_ITEM_NOT_EXIST;
            break;
        case (KCM_STATUS_STORAGE_ERROR):
            fcc_status = FCC_STATUS_KCM_STORAGE_ERROR;
            break;
        case (KCM_STATUS_FILE_EXIST):
            fcc_status = FCC_STATUS_KCM_FILE_EXIST_ERROR;
            break;
        case (KCM_CRYPTO_STATUS_UNSUPPORTED_HASH_MODE):
        case (KCM_CRYPTO_STATUS_PARSING_DER_PRIVATE_KEY):
        case (KCM_CRYPTO_STATUS_PARSING_DER_PUBLIC_KEY):
        case (KCM_CRYPTO_STATUS_PK_KEY_INVALID_FORMAT):
        case (KCM_CRYPTO_STATUS_INVALID_PK_PUBKEY):
        case (KCM_CRYPTO_STATUS_ECP_INVALID_KEY):
        case (KCM_CRYPTO_STATUS_PK_KEY_INVALID_VERSION):
        case (KCM_CRYPTO_STATUS_PK_PASSWORD_REQUIRED):
        case (KCM_CRYPTO_STATUS_PRIVATE_KEY_VERIFICATION_FAILED):
        case (KCM_CRYPTO_STATUS_PUBLIC_KEY_VERIFICATION_FAILED):
        case (KCM_CRYPTO_STATUS_PK_UNKNOWN_PK_ALG):
        case (KCM_CRYPTO_STATUS_UNSUPPORTED_CURVE):
        case (KCM_CRYPTO_STATUS_PARSING_DER_CERT):
        case (KCM_CRYPTO_STATUS_CERT_EXPIRED):
        case (KCM_CRYPTO_STATUS_CERT_FUTURE):
        case (KCM_CRYPTO_STATUS_CERT_MD_ALG):
        case (KCM_CRYPTO_STATUS_CERT_PUB_KEY_TYPE):
        case (KCM_CRYPTO_STATUS_CERT_PUB_KEY):
        case (KCM_CRYPTO_STATUS_CERT_NOT_TRUSTED):
        case (KCM_CRYPTO_STATUS_INVALID_X509_ATTR):
        case (KCM_CRYPTO_STATUS_VERIFY_SIGNATURE_FAILED):
        case (KCM_CRYPTO_STATUS_INVALID_MD_TYPE):
        case (KCM_CRYPTO_STATUS_FAILED_TO_WRITE_SIGNATURE):
            fcc_status = FCC_STATUS_KCM_CRYPTO_ERROR;
            break;
        default:
            SA_PV_LOG_INFO("Invalid kcm_result result (%u)!", kcm_result);
            fcc_status = FCC_STATUS_ERROR;
            break;
    }
    return fcc_status;
}
