Simple interface for Mbed Cloud Client
Embed:
(wiki syntax)
Show/hide line numbers
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 }
Generated on Tue Jul 12 2022 19:01:34 by 1.7.2