Simple interface for Mbed Cloud Client

Dependents:  

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers fcc_verification.c Source File

fcc_verification.c

00001 // ----------------------------------------------------------------------------
00002 // Copyright 2016-2017 ARM Ltd.
00003 //  
00004 // Licensed under the Apache License, Version 2.0 (the "License");
00005 // you may not use this file except in compliance with the License.
00006 // You may obtain a copy of the License at
00007 //  
00008 //     http://www.apache.org/licenses/LICENSE-2.0
00009 //  
00010 // Unless required by applicable law or agreed to in writing, software
00011 // distributed under the License is distributed on an "AS IS" BASIS,
00012 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013 // See the License for the specific language governing permissions and
00014 // limitations under the License.
00015 // ----------------------------------------------------------------------------
00016 
00017 #include "factory_configurator_client.h"
00018 #include "fcc_status.h"
00019 #include "fcc_verification.h"
00020 #include "key_config_manager.h"
00021 #include "pv_error_handling.h"
00022 #include "cs_der_certs.h"
00023 #include "cs_utils.h"
00024 #include "fcc_output_info_handler.h"
00025 #include "fcc_malloc.h"
00026 #include "time.h"
00027 #include "cs_der_keys.h"
00028 #include "cs_utils.h"
00029 #include "fcc_sotp.h"
00030 #include "common_utils.h"
00031 #include "kcm_internal.h"
00032 
00033 #define FCC_10_YEARS_IN_SECONDS 315360000//10*365*24*60*60
00034 
00035 /*
00036 * The function checks that UTC offset value is inside defined range of valid offsets :-12:00 - +14:00
00037 */
00038 static bool check_utc_offset_data(char *utc_offset_data, size_t utc_data_size)
00039 {
00040     uint8_t symbol_index = 0;
00041     uint8_t first_digit_of_hour = 1;
00042     uint8_t second_digit_of_hour = 2;
00043     uint8_t first_digit_of_minutes = 4;
00044     uint8_t second_digit_of_minutes = 5;
00045 
00046     SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS();
00047 
00048     /*
00049     The range of UTC offsets taken from https://en.wikipedia.org/wiki/List_of_UTC_time_offsets
00050     We check only that the offset is -xx:yy or +xx:yy and that the offset is in range of offsets : -12:00 - +14:00
00051     but we check only that UTC contain restricted symbols(-,+,:_) and numbers at xx or yy.
00052     */
00053     //The first char must be '+' or '-'
00054     if ((utc_offset_data[symbol_index] != '+') && (utc_offset_data[symbol_index] != '-')) {
00055         return false;
00056     }
00057 
00058     //The format of utc offset should be -xx:xx or +xx:xx
00059     if (utc_offset_data[3] != ':') {
00060         return false;
00061     }
00062 
00063     //Check that all numbers of hours and minutes are valid
00064     if (utc_offset_data[first_digit_of_hour] < '0' || utc_offset_data[first_digit_of_hour] > '9') {
00065         return false;
00066     }
00067     if (utc_offset_data[second_digit_of_hour] < '0' || utc_offset_data[second_digit_of_hour] > '9') {
00068         return false;
00069     }
00070     if (utc_offset_data[first_digit_of_minutes] < '0' || utc_offset_data[first_digit_of_minutes] > '9') {
00071         return false;
00072     }
00073     if (utc_offset_data[second_digit_of_minutes] < '0' || utc_offset_data[second_digit_of_minutes] > '9') {
00074         return false;
00075     }
00076 
00077     SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS();
00078     return true;
00079 }
00080 
00081 /** The function checks bootstrap server uri data contents.
00082 *
00083 * @param uri_data_buffer[in]             The bootstrap uri data.
00084 * @param size_of_uri_data_buffer[in]      The bootstrap uri data size.
00085 * @return
00086 *     fcc_status_e.
00087 */
00088 static fcc_status_e  fcc_check_uri_contents(bool use_bootstrap, uint8_t* uri_data_buffer, size_t size_of_uri_data_buffer)
00089 {
00090     const char uri_coap_prefix[] = "coap://";
00091     const char uri_coaps_prefix[] = "coaps://";
00092     const char uri_aid_1[] = "?aid=";
00093     const char uri_aid_2[] = "&aid=";
00094     bool has_uri_aid = false;
00095     fcc_status_e  fcc_status = FCC_STATUS_SUCCESS;
00096     char *uri_string = NULL;
00097     kcm_status_e  kcm_status = KCM_STATUS_SUCCESS;
00098     bool is_first_to_claim_mode = false;
00099     uint32_t first_to_claim = 0;
00100     size_t act_config_param_size = 0;
00101 
00102     SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS();
00103 
00104     // get first to claim
00105     kcm_status = kcm_item_get_data((const uint8_t*)g_fcc_first_to_claim_parameter_name,
00106                                    strlen(g_fcc_first_to_claim_parameter_name),
00107                                    KCM_CONFIG_ITEM,
00108                                    (uint8_t*)&first_to_claim,
00109                                    sizeof(uint32_t),
00110                                    &act_config_param_size);
00111     SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS && kcm_status != KCM_STATUS_ITEM_NOT_FOUND), FCC_STATUS_KCM_ERROR, "Failed to get first to claim config parameter");
00112     if (kcm_status == KCM_STATUS_SUCCESS) {
00113         SA_PV_ERR_RECOVERABLE_RETURN_IF((act_config_param_size != sizeof(uint32_t)), FCC_STATUS_WRONG_ITEM_DATA_SIZE, "Size of first to claim mode parameter is wrong ");
00114         is_first_to_claim_mode = (first_to_claim == 1);
00115     }
00116 
00117     //Allocate buffer for uri string creation
00118     uri_string = fcc_malloc(size_of_uri_data_buffer + 1);
00119     SA_PV_ERR_RECOVERABLE_RETURN_IF((uri_string == NULL), FCC_STATUS_MEMORY_OUT, "Failed to allocate memory for URI string");
00120 
00121     //Copy data and create null terminated string
00122     memcpy(uri_string, uri_data_buffer, size_of_uri_data_buffer);
00123     (*(uri_string + size_of_uri_data_buffer)) = '\0';
00124 
00125     // Check that uri_string has correct prefix
00126     if (memcmp(uri_string, uri_coap_prefix, strlen(uri_coap_prefix)) != 0 && memcmp(uri_string, uri_coaps_prefix, strlen(uri_coaps_prefix)) != 0) {
00127         SA_PV_ERR_RECOVERABLE_GOTO_IF(true, fcc_status = FCC_STATUS_URI_WRONG_FORMAT, exit, "Wrong uri prefix");
00128     }
00129 
00130     // Check if uri_string contains uri_aid (indicate the uri contains AccountId)
00131     if ((strstr(uri_string, uri_aid_1) != NULL) || (strstr(uri_string, uri_aid_2) != NULL)) {
00132         has_uri_aid = true;
00133     }
00134 
00135     if (is_first_to_claim_mode == true) {
00136         SA_PV_ERR_RECOVERABLE_GOTO_IF(use_bootstrap == false, fcc_status = FCC_STATUS_FIRST_TO_CLAIM_NOT_ALLOWED, exit, "First to claim not allowed in lwm2m mode");
00137         SA_PV_ERR_RECOVERABLE_GOTO_IF(has_uri_aid == true, fcc_status = FCC_STATUS_FIRST_TO_CLAIM_NOT_ALLOWED, exit, "First to claim not allowed if account ID exist");
00138     } else {
00139         SA_PV_ERR_RECOVERABLE_GOTO_IF(has_uri_aid == false, fcc_status = FCC_STATUS_URI_WRONG_FORMAT, exit, "Wrong uri data");
00140     }
00141 
00142 exit:
00143     fcc_free(uri_string);
00144     SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS();
00145     return fcc_status;
00146 }
00147 
00148 /* The function verifies if current item exists and checks the result with is_should_be_present flag.
00149 *  In case of unsuitability of the flag and existence of the item, the function sets warning with relevant message.
00150 */
00151 static fcc_status_e  verify_existence_and_set_warning(const uint8_t *parameter_name, size_t size_of_parameter_name, kcm_item_type_e parameter_type, bool is_should_be_present)
00152 {
00153     kcm_status_e  kcm_status = KCM_STATUS_SUCCESS;
00154     fcc_status_e  output_info_fcc_status = FCC_STATUS_SUCCESS;
00155     fcc_status_e  fcc_status = FCC_STATUS_SUCCESS;
00156     size_t item_size = 0;
00157 
00158     SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS();
00159 
00160     //Check that second mode server uri is not present
00161     kcm_status = kcm_item_get_data_size(parameter_name,
00162                                         size_of_parameter_name,
00163                                         parameter_type,
00164                                         &item_size);
00165 
00166     if (kcm_status == KCM_STATUS_SUCCESS && is_should_be_present == false) {
00167         output_info_fcc_status = fcc_store_warning_info((const uint8_t*)parameter_name, size_of_parameter_name, g_fcc_redundant_item_warning_str);
00168     }
00169     if (kcm_status != KCM_STATUS_SUCCESS &&  is_should_be_present == true) {
00170         output_info_fcc_status = fcc_store_warning_info((const uint8_t*)parameter_name, size_of_parameter_name, g_fcc_item_not_set_warning_str);
00171     }
00172     SA_PV_ERR_RECOVERABLE_RETURN_IF((output_info_fcc_status != FCC_STATUS_SUCCESS),
00173                                     fcc_status = FCC_STATUS_WARNING_CREATE_ERROR,
00174                                     "Failed to create warning");
00175 
00176     SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS();
00177     return fcc_status;
00178 }
00179 /**This function verifies certificate expiration according to
00180 *
00181 * @param certificate_data[in]                  buffer of certificate.
00182 * @param size_of_certificate_data[in]          size of certificate data.
00183 * @param certificate_name[in]                  buffer of certificate name.
00184 * @param size_of_certificate_name[in]          size of certificate name buffer.
00185 *    @returns
00186 *        fcc_status_e status.
00187 */
00188 static fcc_status_e  verify_certificate_expiration(palX509Handle_t x509_cert, const uint8_t *certificate_name, size_t size_of_certificate_name)
00189 {
00190     fcc_status_e  fcc_status = FCC_STATUS_SUCCESS;
00191     kcm_status_e  kcm_status = KCM_STATUS_SUCCESS;
00192     fcc_status_e  output_info_fcc_status = FCC_STATUS_SUCCESS;
00193     size_t size_of_valid_from_attr = 0;
00194     size_t size_of_valid_until_attr = 0;
00195     uint64_t valid_from_attr = 0;
00196     uint64_t time = 0;
00197     uint64_t diff_time = 60; //seconds. This value used to reduce time adjustment 
00198     uint64_t valid_until_attr = 0;
00199 
00200     SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS();
00201 
00202     //Get "valid_from" certificate attribute
00203     kcm_status = cs_attr_get_data_x509_cert(x509_cert,
00204                                             CS_VALID_FROM_ATTRIBUTE_TYPE,
00205                                             (uint8_t*)&valid_from_attr,
00206                                             sizeof(uint64_t),
00207                                             &size_of_valid_from_attr);
00208     SA_PV_ERR_RECOVERABLE_GOTO_IF(kcm_status != KCM_STATUS_SUCCESS, fcc_status = FCC_STATUS_INVALID_CERT_ATTRIBUTE, exit, "Failed to get valid_from attribute");
00209 
00210     //Get "valid_until" certificate attribute
00211     kcm_status = cs_attr_get_data_x509_cert(x509_cert,
00212                                             CS_VALID_TO_ATTRIBUTE_TYPE,
00213                                             (uint8_t*)&valid_until_attr,
00214                                             sizeof(uint64_t),
00215                                             &size_of_valid_until_attr);
00216     SA_PV_ERR_RECOVERABLE_GOTO_IF(kcm_status != KCM_STATUS_SUCCESS, fcc_status = FCC_STATUS_INVALID_CERT_ATTRIBUTE, exit, "Failed to get valid_until attribute");
00217 
00218 
00219     //Check device time
00220     time = pal_osGetTime();
00221     if (time == 0) {
00222         output_info_fcc_status = fcc_store_warning_info((const uint8_t*)certificate_name, size_of_certificate_name, g_fcc_cert_time_validity_warning_str);
00223         SA_PV_LOG_ERR("time is (%" PRIuMAX ") ", (uint64_t)time);
00224         SA_PV_ERR_RECOVERABLE_GOTO_IF((output_info_fcc_status != FCC_STATUS_SUCCESS), fcc_status = FCC_STATUS_WARNING_CREATE_ERROR, exit, "Failed to create warning");
00225     } else {
00226         //Check that the certificate is not expired
00227         SA_PV_ERR_RECOVERABLE_GOTO_IF((time > (valid_until_attr)), fcc_status = FCC_STATUS_EXPIRED_CERTIFICATE, exit, "The certificate is expired");
00228 
00229         //Check that start of validity is less than current time
00230         if (time + diff_time < (valid_from_attr)) {
00231             SA_PV_LOG_ERR("valid_from_attr is (%" PRIuMAX ") ", (uint64_t)(valid_from_attr));
00232             SA_PV_LOG_ERR("time is (%" PRIuMAX ") ", (uint64_t)time);
00233             output_info_fcc_status = fcc_store_warning_info((const uint8_t*)certificate_name, size_of_certificate_name, g_fcc_cert_time_validity_warning_str);
00234             SA_PV_ERR_RECOVERABLE_GOTO_IF((output_info_fcc_status != FCC_STATUS_SUCCESS), fcc_status = FCC_STATUS_WARNING_CREATE_ERROR, exit, "Failed to create warning");
00235         }
00236 
00237         //Check that the certificate is valid at least for 10 years
00238         if ((valid_until_attr)-time < FCC_10_YEARS_IN_SECONDS) {
00239             output_info_fcc_status = fcc_store_warning_info((const uint8_t*)certificate_name, size_of_certificate_name, g_fcc_cert_validity_less_10_years_warning_str);
00240             SA_PV_ERR_RECOVERABLE_GOTO_IF((output_info_fcc_status != FCC_STATUS_SUCCESS), fcc_status = FCC_STATUS_WARNING_CREATE_ERROR, exit, "Failed to create warning");
00241         }
00242 
00243     }
00244 exit:
00245     if (fcc_status != FCC_STATUS_SUCCESS) {
00246         output_info_fcc_status = fcc_store_error_info((const uint8_t*)certificate_name, size_of_certificate_name, fcc_status);
00247         SA_PV_ERR_RECOVERABLE_RETURN_IF((output_info_fcc_status != FCC_STATUS_SUCCESS), fcc_status = FCC_STATUS_OUTPUT_INFO_ERROR, "Failed to create output fcc_status error %d", fcc_status);
00248     }
00249     SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS();
00250     return fcc_status;
00251 }
00252 /**This function verifies lwm2m certificate ou attribute is equal to aid from server link.
00253 *
00254 * @param certificate_data[in]                  buffer of certificate.
00255 * @param size_of_certificate_data[in]          size of certificate data.
00256 *        fcc_status_e status.
00257 */
00258 static fcc_status_e  compare_ou_with_aid_server(palX509Handle_t x509_cert)
00259 {
00260     fcc_status_e  fcc_status = FCC_STATUS_SUCCESS;
00261     uint8_t *ou_attribute_data = NULL;
00262     size_t ou_attribute_size = 0;
00263     uint8_t *parameter_name = (uint8_t*)g_fcc_lwm2m_server_uri_name;
00264     size_t size_of_parameter_name = strlen(g_fcc_lwm2m_server_uri_name);
00265     uint8_t *server_uri_buffer = NULL;
00266     size_t item_size = 0;
00267     char *uri_string = NULL;
00268     char *aid_substring = NULL;
00269     int aid_substring_size = 0;
00270     int result = 0;
00271     int len_of_aid_sub_string = (int)strlen("&aid=");
00272 
00273     //Get OU certificate attribute
00274     fcc_status = fcc_get_certificate_attribute(x509_cert, CS_OU_ATTRIBUTE_TYPE, &ou_attribute_data, &ou_attribute_size);
00275     SA_PV_ERR_RECOVERABLE_RETURN_IF(fcc_status != FCC_STATUS_SUCCESS, fcc_status = fcc_status, "Failed to get size OU attribute");
00276 
00277     //Get aid data
00278     fcc_status = fcc_get_kcm_data(parameter_name, size_of_parameter_name, KCM_CONFIG_ITEM, &server_uri_buffer, &item_size);
00279     SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status = fcc_status, exit, "Failed to get kcm data server url");
00280 
00281     uri_string = fcc_malloc(item_size + 1);
00282     SA_PV_ERR_RECOVERABLE_GOTO_IF((uri_string == NULL), fcc_status = FCC_STATUS_MEMORY_OUT, exit, "Failed to get kcm data server url");
00283 
00284     memcpy(uri_string, server_uri_buffer, item_size);
00285     (*(uri_string + item_size)) = '\0';
00286 
00287     aid_substring = strstr(uri_string, "&aid=");
00288     if (aid_substring == NULL) {
00289         aid_substring = strstr(uri_string, "?aid=");
00290         SA_PV_ERR_RECOVERABLE_GOTO_IF((aid_substring == NULL), fcc_status = FCC_STATUS_URI_WRONG_FORMAT, exit, "URI format is wrong");
00291     }
00292 
00293     aid_substring_size = (int)strlen(aid_substring);
00294     aid_substring_size = aid_substring_size - len_of_aid_sub_string;
00295     SA_PV_ERR_RECOVERABLE_GOTO_IF((aid_substring_size < (int)ou_attribute_size - 1), fcc_status = FCC_STATUS_URI_WRONG_FORMAT, exit, "URI format is wrong");
00296 
00297     result = memcmp(&(aid_substring[len_of_aid_sub_string]), ou_attribute_data, ou_attribute_size);
00298     SA_PV_ERR_RECOVERABLE_GOTO_IF((result != 0), fcc_status = FCC_STATUS_INVALID_LWM2M_CN_ATTR, exit, "CN of LWM2M different from endpoint name");
00299 
00300 exit:
00301     fcc_free(ou_attribute_data);
00302     fcc_free(server_uri_buffer);
00303     fcc_free(uri_string);
00304     return fcc_status;
00305 }
00306 /**This function verifies  certificate's cn attribute is equal to endpoint name.
00307 *
00308 * @param certificate_data[in]                  buffer of certificate.
00309 * @param size_of_certificate_data[in]          size of certificate data.
00310 *        fcc_status_e status.
00311 */
00312 static fcc_status_e  compare_cn_with_endpoint(palX509Handle_t x509_cert)
00313 {
00314     fcc_status_e  fcc_status = FCC_STATUS_SUCCESS;
00315     //fcc_status_e output_info_fcc_status = FCC_STATUS_SUCCESS;
00316     size_t size_of_cn_attr = 0;
00317     uint8_t *cn_attribute_data = NULL;
00318     size_t endpoint_name_size;
00319     uint8_t *endpoint_name_data = NULL;
00320     int result = 0;
00321 
00322     //Get  CN certificate attribute
00323     fcc_status = fcc_get_certificate_attribute(x509_cert, CS_CN_ATTRIBUTE_TYPE, &cn_attribute_data, &size_of_cn_attr);
00324     SA_PV_ERR_RECOVERABLE_RETURN_IF(fcc_status != FCC_STATUS_SUCCESS, fcc_status = fcc_status, "Failed to get size CN attribute");
00325 
00326     //Get attribute returns size of string including  "\0"
00327     size_of_cn_attr = size_of_cn_attr - 1;
00328 
00329     //Get endpoint name size
00330     fcc_status = fcc_get_kcm_data((const uint8_t*)g_fcc_endpoint_parameter_name, strlen(g_fcc_endpoint_parameter_name), KCM_CONFIG_ITEM, &endpoint_name_data, &endpoint_name_size);
00331     SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status = fcc_status, exit, "Failed to get endpoint name");
00332     SA_PV_ERR_RECOVERABLE_GOTO_IF((size_of_cn_attr != endpoint_name_size), fcc_status = FCC_STATUS_INVALID_LWM2M_CN_ATTR, exit, "Wrong size of CN");
00333 
00334     result = memcmp(endpoint_name_data, cn_attribute_data, size_of_cn_attr);
00335     SA_PV_ERR_RECOVERABLE_GOTO_IF((result != 0), fcc_status = FCC_STATUS_INVALID_LWM2M_CN_ATTR, exit, "CN of the certificate is different from endpoint name");
00336 
00337 exit:
00338     fcc_free(cn_attribute_data);
00339     fcc_free(endpoint_name_data);
00340     return fcc_status;
00341 }
00342 /** The function checks validity of bootstrap server uri parameter
00343 *
00344 * The function checks the item's size, gets its data and checks it.
00345 *
00346 * @param bootrstrap_server_uri_name[in]             The bootstrap uri name.
00347 * @param size_of_bootrstrap_server_uri_name[in]     The size of bootstrap uri name.
00348 * @return
00349 *     fcc_status_e.
00350 */
00351 static fcc_status_e  verify_server_uri(bool use_bootstrap)
00352 {
00353 
00354     fcc_status_e  fcc_status = FCC_STATUS_SUCCESS;
00355     fcc_status_e  output_info_fcc_status = FCC_STATUS_SUCCESS;
00356     kcm_status_e  kcm_status = KCM_STATUS_SUCCESS;
00357     size_t item_size = 0;
00358     uint8_t *server_uri_buffer = NULL;
00359     uint8_t *parameter_name = NULL;
00360     size_t size_of_parameter_name = 0;
00361     uint8_t *second_mode_parameter_name = NULL;
00362     size_t size_of_second_mode_parameter_name = 0;
00363 
00364     SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS();
00365 
00366     //Set server uri parameter names of current and second mode according to bootstrap mode
00367     if (use_bootstrap == true) {
00368         parameter_name = (uint8_t*)g_fcc_bootstrap_server_uri_name;
00369         size_of_parameter_name = strlen(g_fcc_bootstrap_server_uri_name);
00370         second_mode_parameter_name = (uint8_t*)g_fcc_lwm2m_server_uri_name;
00371         size_of_second_mode_parameter_name = strlen(g_fcc_lwm2m_server_uri_name);
00372     } else {
00373         parameter_name = (uint8_t*)g_fcc_lwm2m_server_uri_name;
00374         size_of_parameter_name = strlen(g_fcc_lwm2m_server_uri_name);
00375         second_mode_parameter_name = (uint8_t*)g_fcc_bootstrap_server_uri_name;
00376         size_of_second_mode_parameter_name = strlen(g_fcc_bootstrap_server_uri_name);
00377     }
00378     fcc_status = fcc_get_kcm_data(parameter_name, size_of_parameter_name, KCM_CONFIG_ITEM, &server_uri_buffer, &item_size);
00379     SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status = fcc_status, exit, "Failed to get kcm data server url");
00380 
00381     //Check that server uri of second mode is not present, if yes - set warning
00382     fcc_status = verify_existence_and_set_warning(second_mode_parameter_name, size_of_second_mode_parameter_name, KCM_CONFIG_ITEM, false);
00383     SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status = fcc_status, exit, "Failed to verify_existence_and_set_warning");
00384 
00385     //Check server uri data
00386     fcc_status = fcc_check_uri_contents(use_bootstrap, server_uri_buffer, item_size);
00387     SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status = fcc_status, exit, "Failed to check bootstrap uri data");
00388 
00389 exit:
00390     fcc_free(server_uri_buffer);
00391     //In case kcm or fcc error, record the error with parameter name
00392     if (kcm_status != KCM_STATUS_SUCCESS || fcc_status != FCC_STATUS_SUCCESS) {
00393         if (fcc_status == FCC_STATUS_FIRST_TO_CLAIM_NOT_ALLOWED && parameter_name == (uint8_t*)g_fcc_lwm2m_server_uri_name)
00394         {
00395             // In case that using lwm2m and first to claim on, change the parameter_name
00396             parameter_name = (uint8_t*)g_fcc_first_to_claim_parameter_name;
00397             size_of_parameter_name = strlen(g_fcc_first_to_claim_parameter_name);
00398         }
00399         output_info_fcc_status = fcc_store_error_info(parameter_name, size_of_parameter_name, fcc_status);
00400         SA_PV_ERR_RECOVERABLE_RETURN_IF((output_info_fcc_status != FCC_STATUS_SUCCESS),
00401                                         fcc_status = FCC_STATUS_OUTPUT_INFO_ERROR,
00402                                         "Failed to create output fcc_status error %d",
00403                                         fcc_status);
00404     }
00405     SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS();
00406     return fcc_status;
00407 }
00408 
00409 /* The function checks UTC offset.
00410 */
00411 static fcc_status_e  check_utc_offset(void)
00412 {
00413     fcc_status_e  fcc_status = FCC_STATUS_SUCCESS;
00414     fcc_status_e  fcc_output_status = FCC_STATUS_SUCCESS;
00415     uint8_t *parameter_name = (uint8_t*)g_fcc_offset_from_utc_parameter_name;
00416     size_t size_of_parameter_name = strlen(g_fcc_offset_from_utc_parameter_name);
00417     fcc_status_e  output_info_fcc_status = FCC_STATUS_SUCCESS;
00418     size_t item_size = 0;
00419 
00420     uint8_t *utc_offset_data = NULL;
00421     bool status = false;
00422 
00423     SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS();
00424 
00425     fcc_status = fcc_get_kcm_data(parameter_name, size_of_parameter_name, KCM_CONFIG_ITEM, &utc_offset_data, &item_size);
00426 
00427     //If the item is missing or empty, write warning
00428     if (fcc_status == FCC_STATUS_ITEM_NOT_EXIST || fcc_status == FCC_STATUS_EMPTY_ITEM) {
00429         fcc_output_status = fcc_store_warning_info(parameter_name, size_of_parameter_name, g_fcc_item_not_set_warning_str);
00430         SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_output_status != FCC_STATUS_SUCCESS),
00431                                       fcc_status = FCC_STATUS_WARNING_CREATE_ERROR,
00432                                       exit,
00433                                       "Failed to create output warning %s",
00434                                       g_fcc_item_not_set_warning_str);
00435         fcc_status = FCC_STATUS_SUCCESS;
00436     } else {
00437         //If get kcm data returned error, exit with error
00438         SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status = fcc_status, exit, "Failed to get utc data");
00439 
00440         status = check_utc_offset_data((char*)utc_offset_data, item_size);
00441         SA_PV_ERR_RECOVERABLE_GOTO_IF((status != true), fcc_status = FCC_STATUS_UTC_OFFSET_WRONG_FORMAT, exit, "Failed to check utc offset");
00442     }
00443 
00444 exit:
00445     fcc_free(utc_offset_data);
00446     if (fcc_status != FCC_STATUS_SUCCESS) {
00447         output_info_fcc_status = fcc_store_error_info(parameter_name, size_of_parameter_name, fcc_status);
00448         SA_PV_ERR_RECOVERABLE_RETURN_IF((output_info_fcc_status != FCC_STATUS_SUCCESS),
00449                                         fcc_status = FCC_STATUS_OUTPUT_INFO_ERROR,
00450                                         "Failed to create output fcc_status error  %d",
00451                                         fcc_status);
00452     }
00453     SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS();
00454     return fcc_status;
00455 }
00456 /**This function checks Root CA certificate.
00457 *
00458 * @param device_objects[in]         Structure with set of device security object data.
00459 * @param use_bootstrap[in]          Bootstrap mode.
00460 *    @returns
00461 *        fcc_status_e status.
00462 */
00463 static fcc_status_e  verify_root_ca_certificate(bool use_bootstrap)
00464 {
00465     fcc_status_e  fcc_status = FCC_STATUS_SUCCESS;
00466     fcc_status_e  output_info_fcc_status = FCC_STATUS_SUCCESS;
00467     kcm_status_e  kcm_status = KCM_STATUS_SUCCESS;
00468     size_t item_size = 0;
00469     uint8_t *parameter_name = NULL;
00470     size_t size_of_parameter_name = 0;
00471     uint8_t *second_mode_parameter_name = NULL;
00472     size_t size_of_second_mode_parameter_name = 0;
00473     uint8_t attribute_data[PAL_CERT_ID_SIZE] = { 0 };
00474     size_t size_of_attribute_data = 0;
00475     uint8_t data_out[FCC_CA_IDENTIFICATION_SIZE] = { 0 };
00476     size_t data_size_out = 0;
00477     int result = 0;
00478 
00479 
00480     SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS();
00481 
00482     //Set CA certificate names of current and second mode
00483     if (use_bootstrap == true) {
00484         //Set bootstrap root ca certificate name
00485         parameter_name = (uint8_t*)g_fcc_bootstrap_server_ca_certificate_name;
00486         size_of_parameter_name = strlen(g_fcc_bootstrap_server_ca_certificate_name);
00487         second_mode_parameter_name = (uint8_t*)g_fcc_lwm2m_server_ca_certificate_name;
00488         size_of_second_mode_parameter_name = strlen(g_fcc_lwm2m_server_ca_certificate_name);
00489     } else {
00490         //Set lwm2m root ca certificate name
00491         parameter_name = (uint8_t*)g_fcc_lwm2m_server_ca_certificate_name;
00492         size_of_parameter_name = strlen(g_fcc_lwm2m_server_ca_certificate_name);
00493         second_mode_parameter_name = (uint8_t*)g_fcc_bootstrap_server_ca_certificate_name;
00494         size_of_second_mode_parameter_name = strlen(g_fcc_bootstrap_server_ca_certificate_name);
00495     }
00496 
00497     //Check that ca certificate of current mode is present 
00498     kcm_status = kcm_item_get_data_size((const uint8_t*)parameter_name,
00499                                         size_of_parameter_name,
00500                                         KCM_CERTIFICATE_ITEM,
00501                                         &item_size);
00502     SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), fcc_status = FCC_STATUS_ITEM_NOT_EXIST, store_error_and_exit, "Failed to get size bootstrap root ca certificate size");
00503     SA_PV_ERR_RECOVERABLE_GOTO_IF((item_size == 0), fcc_status = FCC_STATUS_EMPTY_ITEM, store_error_and_exit, "Empty root CA certificate");
00504 
00505     //Check  that ca certificate of second mode is not present, if yes - set warning
00506     fcc_status = verify_existence_and_set_warning(second_mode_parameter_name, size_of_second_mode_parameter_name, KCM_CERTIFICATE_ITEM, false);
00507     SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status = fcc_status, store_error_and_exit, "Failed in verify_existence_and_set_warning");
00508 
00509     if (use_bootstrap == true) {
00510         fcc_status = fcc_get_certificate_attribute_by_name((const uint8_t*)parameter_name,
00511                                                            size_of_parameter_name,
00512                                                            CS_CERT_ID_ATTR,
00513                                                            attribute_data,
00514                                                            sizeof(attribute_data),
00515                                                            &size_of_attribute_data);
00516         SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status = fcc_status, store_error_and_exit, "Failed to get ca id attribute");
00517 
00518         fcc_status = fcc_sotp_data_retrieve(data_out, size_of_attribute_data, &data_size_out, SOTP_TYPE_TRUSTED_TIME_SRV_ID);
00519 
00520         if (fcc_status != FCC_STATUS_SUCCESS || data_size_out != size_of_attribute_data) {
00521             output_info_fcc_status = fcc_store_warning_info((const uint8_t*)parameter_name, size_of_parameter_name, g_fcc_ca_identifier_warning_str);
00522             SA_PV_ERR_RECOVERABLE_GOTO_IF((output_info_fcc_status != FCC_STATUS_SUCCESS), fcc_status = FCC_STATUS_WARNING_CREATE_ERROR, store_error_and_exit, "Failed to create warning");
00523         }
00524 
00525         if (fcc_status == FCC_STATUS_SUCCESS) {
00526             result = memcmp(data_out, attribute_data, data_size_out);
00527             if (result != 0) {
00528                 output_info_fcc_status = fcc_store_warning_info((const uint8_t*)parameter_name, size_of_parameter_name, g_fcc_ca_identifier_warning_str);
00529                 SA_PV_ERR_RECOVERABLE_GOTO_IF((output_info_fcc_status != FCC_STATUS_SUCCESS), fcc_status = FCC_STATUS_WARNING_CREATE_ERROR, store_error_and_exit, "Failed to create warning");
00530             }
00531         }
00532         fcc_status = FCC_STATUS_SUCCESS;
00533     }
00534 
00535     //TBD : check of mbed crypto scheme IOTPREQ-1417
00536 store_error_and_exit:
00537     if (fcc_status != FCC_STATUS_SUCCESS) {
00538         output_info_fcc_status = fcc_store_error_info(parameter_name, size_of_parameter_name, fcc_status);
00539         SA_PV_ERR_RECOVERABLE_RETURN_IF((output_info_fcc_status != FCC_STATUS_SUCCESS),
00540                                         fcc_status = FCC_STATUS_OUTPUT_INFO_ERROR,
00541                                         "Failed to create output fcc_status error  %d",
00542                                         fcc_status);
00543     }
00544     SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS();
00545     return fcc_status;
00546 }
00547 /**This function checks device private key.
00548 *
00549 * @param use_bootstrap[in]          Bootstrap mode.
00550 *    @returns
00551 *        fcc_status_e status.
00552 */
00553 static fcc_status_e  verify_device_certificate_and_private_key(bool use_bootstrap)
00554 {
00555     fcc_status_e  fcc_status = FCC_STATUS_SUCCESS;
00556     fcc_status_e  output_info_fcc_status = FCC_STATUS_SUCCESS;
00557     kcm_status_e  kcm_status = KCM_STATUS_SUCCESS;
00558     size_t size_of_device_cert = 0;
00559     uint8_t *device_cert = NULL;
00560     bool is_self_signed = false;
00561     uint8_t *parameter_name = NULL;
00562     size_t size_of_parameter_name = 0;
00563     uint8_t *second_mode_parameter_name = NULL;
00564     size_t size_of_second_mode_parameter_name = 0;
00565     uint8_t *private_key_data = NULL;
00566     size_t size_of_private_key_data = 0;
00567     palX509Handle_t x509_cert_handle = NULLPTR;
00568 
00569     SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS();
00570 
00571     //Set device privat key names of current and second modes
00572     if (use_bootstrap == true) {
00573         parameter_name = (uint8_t*)g_fcc_bootstrap_device_private_key_name;
00574         size_of_parameter_name = strlen(g_fcc_bootstrap_device_private_key_name);
00575         second_mode_parameter_name = (uint8_t*)g_fcc_lwm2m_device_private_key_name;
00576         size_of_second_mode_parameter_name = strlen(g_fcc_lwm2m_device_private_key_name);
00577     } else {
00578         parameter_name = (uint8_t*)g_fcc_lwm2m_device_private_key_name;
00579         size_of_parameter_name = strlen(g_fcc_lwm2m_device_private_key_name);
00580         second_mode_parameter_name = (uint8_t*)g_fcc_bootstrap_device_private_key_name;
00581         size_of_second_mode_parameter_name = strlen(g_fcc_bootstrap_device_private_key_name);
00582     }
00583 
00584     //FIXME: Device certificate should be verified as chain/
00585     fcc_status = fcc_get_kcm_data(parameter_name, size_of_parameter_name, KCM_PRIVATE_KEY_ITEM, &private_key_data, &size_of_private_key_data);
00586     SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status = fcc_status, store_error_and_exit, "Failed to get device certificate");
00587 
00588     //Check that device private key of second mode is not present, if yes - set warning
00589     fcc_status = verify_existence_and_set_warning(second_mode_parameter_name, size_of_second_mode_parameter_name, KCM_PRIVATE_KEY_ITEM, false);
00590     SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status = fcc_status, store_error_and_exit, "Failed in verify_existence_and_set_warning");
00591 
00592 
00593     //Set parameter names of device certificate according to mode
00594     if (use_bootstrap == true) {
00595         //Set bootstrap root ca certificate name
00596         parameter_name = (uint8_t*)g_fcc_bootstrap_device_certificate_name;
00597         size_of_parameter_name = strlen(g_fcc_bootstrap_device_certificate_name);
00598         second_mode_parameter_name = (uint8_t*)g_fcc_lwm2m_device_certificate_name;
00599         size_of_second_mode_parameter_name = strlen(g_fcc_lwm2m_device_certificate_name);
00600     } else {
00601         //Set lwm2m device certificate name
00602         parameter_name = (uint8_t*)g_fcc_lwm2m_device_certificate_name;
00603         size_of_parameter_name = strlen(g_fcc_lwm2m_device_certificate_name);
00604         second_mode_parameter_name = (uint8_t*)g_fcc_bootstrap_device_certificate_name;
00605         size_of_second_mode_parameter_name = strlen(g_fcc_bootstrap_device_certificate_name);
00606     }
00607 
00608     fcc_status = fcc_get_kcm_data(parameter_name, size_of_parameter_name, KCM_CERTIFICATE_ITEM, &device_cert, &size_of_device_cert);
00609     SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status = fcc_status, store_error_and_exit, "Failed to get device certificate");
00610 
00611     //Create device certificate handle
00612     kcm_status = cs_create_handle_from_der_x509_cert(device_cert, size_of_device_cert, &x509_cert_handle);
00613     SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), fcc_status = FCC_STATUS_INVALID_CERTIFICATE, store_error_and_exit, "Failed to get device certificate descriptor");
00614 
00615     //Check device certificate public key
00616     kcm_status = cs_check_certifcate_public_key(x509_cert_handle, private_key_data, size_of_private_key_data);
00617     SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), fcc_status = FCC_STATUS_CERTIFICATE_PUBLIC_KEY_CORRELATION_ERROR, store_error_and_exit, "Failed to check device certificate public key");
00618 
00619     //Check if the certificate of second mode exists, if yes - set warning
00620     fcc_status = verify_existence_and_set_warning(second_mode_parameter_name, size_of_second_mode_parameter_name, KCM_CERTIFICATE_ITEM, false);
00621     SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status = fcc_status, store_error_and_exit, "Failed to verify_existence_and_set_warning");
00622 
00623     //Compare device certificate's CN attribute with endpoint name
00624     fcc_status = compare_cn_with_endpoint(x509_cert_handle);
00625     SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status = fcc_status, store_error_and_exit, "Failed to compare_cn_with_endpoint");
00626 
00627     //In case LWM2M certificate check it's OU attribute with aid of server link
00628     if (strcmp((const char*)parameter_name, g_fcc_lwm2m_device_certificate_name) == 0) {
00629         fcc_status = compare_ou_with_aid_server(x509_cert_handle);
00630         SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status = fcc_status, store_error_and_exit, "Failed to compare_ou_with_aid_server");
00631     }
00632 
00633     //Check that device certificate not self-signed
00634     kcm_status = cs_is_self_signed_x509_cert(x509_cert_handle, &is_self_signed);
00635     SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), fcc_status = FCC_STATUS_INVALID_CERTIFICATE, store_error_and_exit, "Failed to check if device certificate is self-signed");
00636     if (is_self_signed == true) {
00637         output_info_fcc_status = fcc_store_warning_info(parameter_name, size_of_parameter_name, g_fcc_self_signed_warning_str);
00638         SA_PV_ERR_RECOVERABLE_GOTO_IF((output_info_fcc_status != FCC_STATUS_SUCCESS),
00639                                       fcc_status = FCC_STATUS_WARNING_CREATE_ERROR,
00640                                       store_error_and_exit,
00641                                       "Failed to create warning %s",
00642                                       g_fcc_self_signed_warning_str);
00643     }
00644     //Check device certificate attributes
00645     fcc_status = verify_certificate_expiration(x509_cert_handle, parameter_name, size_of_parameter_name);
00646     SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status = fcc_status, store_error_and_exit, "Failed to verify_certificate_validity");
00647 
00648 store_error_and_exit:
00649     fcc_free(private_key_data);
00650     fcc_free(device_cert);
00651     cs_close_handle_x509_cert(&x509_cert_handle);
00652     if (fcc_status != FCC_STATUS_SUCCESS) {
00653         output_info_fcc_status = fcc_store_error_info(parameter_name, size_of_parameter_name, fcc_status);
00654         SA_PV_ERR_RECOVERABLE_RETURN_IF((output_info_fcc_status != FCC_STATUS_SUCCESS),
00655                                         fcc_status = FCC_STATUS_OUTPUT_INFO_ERROR,
00656                                         "Failed to create output fcc_status error  %d",
00657                                         fcc_status);
00658     }
00659 
00660     SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS();
00661     return fcc_status;
00662 }
00663 
00664 /* The function checks firmware integrity ca and firmware integrity certificates
00665 */
00666 static fcc_status_e  verify_firmware_update_certificate(void)
00667 {
00668     kcm_status_e  kcm_status = KCM_STATUS_SUCCESS;
00669     fcc_status_e  fcc_status = FCC_STATUS_SUCCESS;
00670     fcc_status_e  fcc_output_status = FCC_STATUS_SUCCESS;
00671     fcc_status_e  output_info_fcc_status = FCC_STATUS_SUCCESS;
00672     uint8_t *parameter_name = (uint8_t*)g_fcc_update_authentication_certificate_name;
00673     size_t size_of_parameter_name = strlen(g_fcc_update_authentication_certificate_name);
00674     size_t certificate_data_size = 0;
00675     uint8_t *certificate_data = NULL;
00676     palX509Handle_t x509_cert_handle = NULLPTR;
00677 
00678     SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS();
00679 
00680     fcc_status = fcc_get_kcm_data(parameter_name, size_of_parameter_name, KCM_CERTIFICATE_ITEM, &certificate_data, &certificate_data_size);
00681 
00682     if (fcc_status == FCC_STATUS_ITEM_NOT_EXIST || fcc_status == FCC_STATUS_EMPTY_ITEM) {
00683         fcc_output_status = fcc_store_warning_info((const uint8_t*)parameter_name, size_of_parameter_name, g_fcc_item_not_set_warning_str);
00684         SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_output_status != FCC_STATUS_SUCCESS),
00685                                       fcc_status = FCC_STATUS_WARNING_CREATE_ERROR,
00686                                       exit,
00687                                       "Failed to create output warning %s",
00688                                       g_fcc_item_not_set_warning_str);
00689         fcc_status = FCC_STATUS_SUCCESS;
00690     } else {
00691         //If get kcm data returned error, exit with error
00692         SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status = fcc_status, exit, "Failed to get update certificate data");
00693 
00694         //Create ca firmware integrity certificate handle
00695         kcm_status = cs_create_handle_from_der_x509_cert(certificate_data, certificate_data_size, &x509_cert_handle);
00696         SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), fcc_status = FCC_STATUS_INVALID_CERTIFICATE, exit, "Failed to get device certificate descriptor");
00697 
00698         //Check firmware update certificate expiration
00699         fcc_status = verify_certificate_expiration(x509_cert_handle, parameter_name, size_of_parameter_name);
00700         SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status = fcc_status, exit, "Failed to verify_certificate_validity");
00701     }
00702 
00703 exit:
00704 
00705     fcc_free(certificate_data);
00706     if (x509_cert_handle != NULLPTR) {
00707         cs_close_handle_x509_cert(&x509_cert_handle);
00708     }
00709     if (fcc_status != FCC_STATUS_SUCCESS) {
00710         output_info_fcc_status = fcc_store_error_info(parameter_name, size_of_parameter_name, fcc_status);
00711         SA_PV_ERR_RECOVERABLE_RETURN_IF((output_info_fcc_status != FCC_STATUS_SUCCESS),
00712                                         fcc_status = FCC_STATUS_OUTPUT_INFO_ERROR,
00713                                         "Failed to create output fcc_status error  %d",
00714                                         fcc_status);
00715     }
00716     return fcc_status;
00717 }
00718 
00719 // Check that fcc_firmware_id_name exists and is of correct uuid5 size
00720 /** Check that fcc_firmware_id_name exists and is of correct uuid5 size
00721 *
00722 * @param fcc_firmware_id_name[in]           Name of the file of the uuid (must be either g_fcc_class_id_name or g_fcc_vendor_id_name).
00723 *    @returns
00724 *        FCC_STATUS_SUCCESS If validated successfully, or if the item does not exist (warning is set).
00725 *        Otherwise will return an fcc_status_e error
00726 */
00727 
00728 static fcc_status_e  verify_firmware_uuid(const char *fcc_firmware_id_name)
00729 {
00730     fcc_status_e  fcc_status = FCC_STATUS_SUCCESS;
00731     fcc_status_e  output_info_fcc_status = FCC_STATUS_SUCCESS;
00732     kcm_status_e  kcm_status = KCM_STATUS_SUCCESS;
00733     size_t item_size = 0;
00734 
00735     SA_PV_LOG_TRACE_FUNC_ENTER("fcc_firmware_id_name = %s", fcc_firmware_id_name);
00736 
00737     // Check if class id exists - if not write warning
00738     kcm_status = kcm_item_get_data_size((const uint8_t*)fcc_firmware_id_name,
00739                                         strlen(fcc_firmware_id_name),
00740                                         KCM_CONFIG_ITEM,
00741                                         &item_size);
00742 
00743     if (kcm_status != KCM_STATUS_SUCCESS) {
00744         // If item not found, store warning
00745         if (kcm_status == KCM_STATUS_ITEM_NOT_FOUND) {
00746             fcc_status = fcc_store_warning_info((const uint8_t*)fcc_firmware_id_name, strlen(fcc_firmware_id_name), g_fcc_item_not_set_warning_str);
00747             SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS),
00748                 (fcc_status = FCC_STATUS_WARNING_CREATE_ERROR),
00749                                           Exit,
00750                                           "Failed to create output warning %s",
00751                                           g_fcc_item_not_set_warning_str);
00752 
00753         } else { // If any other KCM error - exit with generic KCM error
00754             fcc_status = FCC_STATUS_KCM_ERROR;
00755 
00756             // Go to Exit returning FCC_STATUS_KCM_ERROR and setting error buffer
00757             goto Exit;
00758         }
00759 
00760     } else {
00761         // If item exists assert item is correct size of UUID5 
00762         SA_PV_ERR_RECOVERABLE_GOTO_IF((item_size != FCC_UUID5_SIZE_IN_BYTES), (fcc_status = FCC_STATUS_WRONG_ITEM_DATA_SIZE), Exit, "Class ID of incorrect size - %" PRIu32, (uint32_t)item_size);
00763     }
00764 
00765 Exit:
00766     if (fcc_status != FCC_STATUS_SUCCESS) {
00767         output_info_fcc_status = fcc_store_error_info((uint8_t*)fcc_firmware_id_name, strlen(fcc_firmware_id_name), fcc_status);
00768         SA_PV_ERR_RECOVERABLE_RETURN_IF((output_info_fcc_status != FCC_STATUS_SUCCESS),
00769                                         FCC_STATUS_OUTPUT_INFO_ERROR,
00770                                         "Failed to create output fcc_status error  %d",
00771                                         fcc_status);
00772     }
00773 
00774     SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS();
00775     return fcc_status;
00776 }
00777 
00778 //FIXME : once init entropy API will be ready,add fcc_is_entropy_initialized implementation
00779 bool fcc_is_entropy_initialized(void)
00780 {
00781     SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS();
00782 
00783     SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS();
00784 
00785     return true;
00786 }
00787 fcc_status_e  fcc_check_time_synchronization()
00788 {
00789 
00790     fcc_status_e  fcc_status = FCC_STATUS_SUCCESS;
00791     fcc_status_e  output_info_fcc_status = FCC_STATUS_SUCCESS;
00792     uint64_t time = 0;
00793     uint8_t *parameter_name = (uint8_t*)g_fcc_device_time_zone_parameter_name;
00794     size_t size_of_parameter_name = strlen(g_fcc_device_time_zone_parameter_name);
00795     size_t item_size = 0;
00796     kcm_status_e  kcm_status = KCM_STATUS_SUCCESS;
00797     /*
00798     Time zone defines -  https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
00799     */
00800     SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS();
00801 
00802     //Check device time
00803     time = pal_osGetTime();
00804     if (time == 0) {
00805         output_info_fcc_status = fcc_store_warning_info((const uint8_t*)g_fcc_current_time_parameter_name, strlen(g_fcc_current_time_parameter_name), g_fcc_item_not_set_warning_str);
00806         SA_PV_ERR_RECOVERABLE_RETURN_IF((output_info_fcc_status != FCC_STATUS_SUCCESS), fcc_status = FCC_STATUS_WARNING_CREATE_ERROR, "Failed to create warning");
00807     }
00808 
00809     //Check device time zone
00810     kcm_status = kcm_item_get_data_size((const uint8_t*)parameter_name,
00811                                         size_of_parameter_name,
00812                                         KCM_CONFIG_ITEM,
00813                                         &item_size);
00814     //Store warning in case time zone is missing or empty
00815     if (kcm_status != KCM_STATUS_SUCCESS || item_size == 0) {
00816         output_info_fcc_status = fcc_store_warning_info(parameter_name, size_of_parameter_name, g_fcc_item_not_set_warning_str);
00817         SA_PV_ERR_RECOVERABLE_RETURN_IF((output_info_fcc_status != FCC_STATUS_SUCCESS),
00818                                         fcc_status = FCC_STATUS_WARNING_CREATE_ERROR,
00819                                         "Failed to create output warning %s",
00820                                         g_fcc_item_not_set_warning_str);
00821     }
00822 
00823     //Check UTC offset
00824     fcc_status = check_utc_offset();
00825     SA_PV_ERR_RECOVERABLE_RETURN_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status, "Failed in check_utc_offset");
00826 
00827     SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS();
00828     return fcc_status;
00829 }
00830 
00831 fcc_status_e  fcc_check_device_general_info()
00832 {
00833     kcm_status_e  kcm_status = KCM_STATUS_SUCCESS;
00834     fcc_status_e  output_info_fcc_status = FCC_STATUS_SUCCESS;
00835     fcc_status_e  fcc_status = FCC_STATUS_SUCCESS;
00836     size_t config_param_size = 0;
00837 
00838     SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS();
00839     //Check FCC_ENDPOINT_NAME_CONFIG_PARAM_NAME
00840     kcm_status = kcm_item_get_data_size((const uint8_t*)&g_fcc_endpoint_parameter_name,
00841                                         strlen(g_fcc_endpoint_parameter_name),
00842                                         KCM_CONFIG_ITEM,
00843                                         &config_param_size);
00844     SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), fcc_status = FCC_STATUS_ITEM_NOT_EXIST, exit, "Failed to get size of %s ", g_fcc_endpoint_parameter_name);
00845     SA_PV_ERR_RECOVERABLE_GOTO_IF((config_param_size == 0), fcc_status = FCC_STATUS_EMPTY_ITEM, exit, "Size of %s is 0 ", g_fcc_endpoint_parameter_name);
00846 
00847 exit:
00848     if (fcc_status != FCC_STATUS_SUCCESS) {
00849         output_info_fcc_status = fcc_store_error_info((const uint8_t*)g_fcc_endpoint_parameter_name, strlen(g_fcc_endpoint_parameter_name), fcc_status);
00850         SA_PV_ERR_RECOVERABLE_RETURN_IF((output_info_fcc_status != FCC_STATUS_SUCCESS),
00851                                         fcc_status = FCC_STATUS_OUTPUT_INFO_ERROR,
00852                                         "Failed to create output fcc_status error %d",
00853                                         fcc_status);
00854     }
00855     SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS();
00856     return fcc_status;
00857 }
00858 
00859 fcc_status_e  fcc_check_device_meta_data(void)
00860 {
00861     int config_param_index = 0;
00862     fcc_status_e  fcc_status = FCC_STATUS_SUCCESS;
00863     fcc_status_e  output_info_fcc_status = FCC_STATUS_SUCCESS;
00864     kcm_status_e  kcm_status = KCM_STATUS_SUCCESS;
00865     size_t config_param_size = 0;
00866     uint8_t *parameter_name = NULL;
00867     size_t size_of_parameter_name = 0;
00868 
00869     SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS();
00870 
00871     for (config_param_index = 0; config_param_index < FCC_MAX_CONFIG_PARAM_TYPE; config_param_index++) {
00872 
00873         //Set current configuration parameter to local variable
00874         parameter_name = (uint8_t*)fcc_config_param_lookup_table[config_param_index].config_param_name;
00875         size_of_parameter_name = strlen(fcc_config_param_lookup_table[config_param_index].config_param_name);
00876 
00877         //Check that current configuration parameter is present
00878         kcm_status = kcm_item_get_data_size((const uint8_t*)parameter_name,
00879                                             size_of_parameter_name,
00880                                             KCM_CONFIG_ITEM,
00881                                             &config_param_size);
00882         SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), fcc_status = FCC_STATUS_ITEM_NOT_EXIST, exit, "Failed to get size of %s ", fcc_config_param_lookup_table[config_param_index].config_param_name);
00883     }
00884 
00885 exit:
00886     if (fcc_status != FCC_STATUS_SUCCESS) {
00887         output_info_fcc_status = fcc_store_error_info(parameter_name, size_of_parameter_name, fcc_status);
00888         SA_PV_ERR_RECOVERABLE_RETURN_IF((output_info_fcc_status != FCC_STATUS_SUCCESS),
00889                                         fcc_status = FCC_STATUS_OUTPUT_INFO_ERROR,
00890                                         "Failed to create output fcc_status error %d",
00891                                         fcc_status);
00892     }
00893     SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS();
00894     return fcc_status;
00895 }
00896 
00897 fcc_status_e  fcc_get_bootstrap_mode(bool *use_bootstrap)
00898 {
00899     kcm_status_e  kcm_status = KCM_STATUS_SUCCESS;
00900     fcc_status_e  fcc_status = FCC_STATUS_SUCCESS;
00901     fcc_status_e  output_info_fcc_status = FCC_STATUS_SUCCESS;
00902     size_t config_param_size = sizeof(uint32_t);
00903     size_t act_config_param_size = 0;
00904     uint32_t bootstrap;
00905     uint8_t *parameter_name = (uint8_t*)g_fcc_use_bootstrap_parameter_name;
00906     size_t size_of_parameter_name = strlen(g_fcc_use_bootstrap_parameter_name);
00907 
00908     SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS();
00909 
00910     //Get configuration parameter
00911     kcm_status = kcm_item_get_data((const uint8_t*)parameter_name,
00912                                    size_of_parameter_name,
00913                                    KCM_CONFIG_ITEM,
00914                                    (uint8_t*)&bootstrap,
00915                                    config_param_size,
00916                                    &act_config_param_size);
00917     SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), fcc_status = FCC_STATUS_ITEM_NOT_EXIST, exit, "Failed to get data bootstrap mode parameter");
00918     SA_PV_ERR_RECOVERABLE_GOTO_IF((act_config_param_size != sizeof(uint32_t)), fcc_status = FCC_STATUS_WRONG_ITEM_DATA_SIZE, exit, "Size of bootstrap mode parameter is wrong ");
00919 
00920     if (bootstrap != 0 && bootstrap != 1) {
00921         SA_PV_ERR_RECOVERABLE_GOTO_IF((true), fcc_status = FCC_STATUS_BOOTSTRAP_MODE_ERROR, exit, "Invalid bootstrap mode");
00922     }
00923     if (bootstrap == 0) {
00924         *use_bootstrap = false;
00925         output_info_fcc_status = fcc_store_warning_info(parameter_name, size_of_parameter_name, g_fcc_bootstrap_mode_false_warning_str);
00926         SA_PV_ERR_RECOVERABLE_GOTO_IF((output_info_fcc_status != FCC_STATUS_SUCCESS),
00927                                       fcc_status = FCC_STATUS_WARNING_CREATE_ERROR,
00928                                       exit,
00929                                       "Failed to create output warning %s",
00930                                       g_fcc_bootstrap_mode_false_warning_str);
00931     } else {
00932         *use_bootstrap = true;
00933     }
00934 
00935 exit:
00936     if (fcc_status != FCC_STATUS_SUCCESS) {
00937         output_info_fcc_status = fcc_store_error_info(parameter_name, size_of_parameter_name, fcc_status);
00938         SA_PV_ERR_RECOVERABLE_RETURN_IF((output_info_fcc_status != FCC_STATUS_SUCCESS),
00939                                         fcc_status = FCC_STATUS_OUTPUT_INFO_ERROR,
00940                                         "Failed to create output fcc_status error  %d",
00941                                         fcc_status);
00942     }
00943     SA_PV_LOG_TRACE_FUNC_EXIT("use_bootstrap is %d", *use_bootstrap);
00944     return fcc_status;
00945 }
00946 
00947 fcc_status_e  fcc_check_device_security_objects(bool use_bootstrap)
00948 {
00949     fcc_status_e  fcc_status = FCC_STATUS_SUCCESS;
00950 
00951     SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS();
00952 
00953     fcc_status = verify_root_ca_certificate(use_bootstrap);
00954     SA_PV_ERR_RECOVERABLE_RETURN_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status, "Failed to verify root CA certificate");
00955 
00956     //Check bootstrap server URI
00957     fcc_status = verify_server_uri(use_bootstrap);
00958     SA_PV_ERR_RECOVERABLE_RETURN_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status, "Failed to verify server URI");
00959 
00960     //Check device certificate and private key
00961     fcc_status = verify_device_certificate_and_private_key(use_bootstrap);
00962     SA_PV_ERR_RECOVERABLE_RETURN_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status, "Failed to verify device certificate and private key");
00963 
00964     SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS();
00965     return fcc_status;
00966 }
00967 
00968 
00969 fcc_status_e  fcc_check_firmware_update_integrity(void)
00970 {
00971     fcc_status_e  fcc_status = FCC_STATUS_SUCCESS;
00972 
00973     SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS();
00974 
00975     fcc_status = verify_firmware_update_certificate();
00976     SA_PV_ERR_RECOVERABLE_RETURN_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status, "Failed to verify integrity CA certificate");
00977 
00978     fcc_status = verify_firmware_uuid(g_fcc_class_id_name);
00979     SA_PV_ERR_RECOVERABLE_RETURN_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status, "Error verifying class ID");
00980 
00981     fcc_status = verify_firmware_uuid(g_fcc_vendor_id_name);
00982     SA_PV_ERR_RECOVERABLE_RETURN_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status, "Error verifying vendor ID");
00983 
00984     SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS();
00985     return fcc_status;
00986 }