Simple interface for Mbed Cloud Client
Embed:
(wiki syntax)
Show/hide line numbers
fcc_bundle_common_utils.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 "fcc_bundle_handler.h" 00018 #include "cn-cbor.h" 00019 #include "pv_error_handling.h" 00020 #include "fcc_bundle_utils.h" 00021 #include "fcc_malloc.h" 00022 #include "general_utils.h" 00023 #include "fcc_utils.h" 00024 #include "factory_configurator_client.h" 00025 00026 #define FCC_MAX_SIZE_OF_STRING 512 00027 00028 /** Gets name from cbor struct. 00029 * 00030 * @param text_cb[in] The cbor text structure 00031 * @param name_out[out] The out buffer for string data 00032 * @param name_len_out[out] The actual size of output buffer 00033 * 00034 * @return 00035 * true for success, false otherwise. 00036 */ 00037 static bool get_data_name(const cn_cbor *text_cb, uint8_t **name_out, size_t *name_len_out) 00038 { 00039 SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS(); 00040 SA_PV_ERR_RECOVERABLE_RETURN_IF((text_cb == NULL), false, "Cbor pointer is NULL"); 00041 SA_PV_ERR_RECOVERABLE_RETURN_IF((name_out == NULL), false, "Invalid pointer for name"); 00042 SA_PV_ERR_RECOVERABLE_RETURN_IF((name_len_out == NULL), false, "Invalid pointer for name_len"); 00043 00044 *name_out = (uint8_t*)fcc_malloc((size_t)(text_cb->length)); 00045 SA_PV_ERR_RECOVERABLE_RETURN_IF((*name_out == NULL), false, "Failed to allocate buffer for name"); 00046 00047 memcpy(*name_out, text_cb->v.bytes, (size_t)text_cb->length); 00048 *name_len_out = (size_t)text_cb->length; 00049 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00050 00051 return true; 00052 } 00053 00054 /** Gets data format from cbor struct 00055 * 00056 * The function goes over all formats and compares it with format from cbor structure. 00057 * 00058 * @param data_cb[in] The cbor text structure 00059 * @param data_format[out] The format of data 00060 * 00061 * @return 00062 * true for success, false otherwise. 00063 */ 00064 static bool get_data_format(const cn_cbor *data_cb, fcc_bundle_data_format_e *data_format) 00065 { 00066 00067 int data_format_index; 00068 bool res; 00069 00070 SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS(); 00071 SA_PV_ERR_RECOVERABLE_RETURN_IF((data_cb == NULL), false, "data_cb is null"); 00072 SA_PV_ERR_RECOVERABLE_RETURN_IF((data_format == NULL), false, "data_format is null"); 00073 SA_PV_ERR_RECOVERABLE_RETURN_IF((*data_format != FCC_INVALID_DATA_FORMAT), false, "wrong data format value"); 00074 00075 for (data_format_index = 0; data_format_index < FCC_MAX_DATA_FORMAT - 1; data_format_index++) { 00076 res = is_memory_equal(fcc_bundle_data_format_lookup_table[data_format_index].data_format_name, 00077 strlen(fcc_bundle_data_format_lookup_table[data_format_index].data_format_name), 00078 data_cb->v.bytes, 00079 (size_t)(data_cb->length)); 00080 if (res) { 00081 *data_format = fcc_bundle_data_format_lookup_table[data_format_index].data_format_type; 00082 return true; 00083 } 00084 } 00085 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00086 return false; 00087 } 00088 00089 bool get_data_buffer_from_cbor(const cn_cbor *data_cb, uint8_t **out_data_buffer, size_t *out_size) 00090 { 00091 00092 cn_cbor_type cb_type; 00093 00094 SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS(); 00095 SA_PV_ERR_RECOVERABLE_RETURN_IF((data_cb == NULL), false, "key_data_cb is null"); 00096 SA_PV_ERR_RECOVERABLE_RETURN_IF((out_size == NULL), false, "Size buffer is null "); 00097 SA_PV_ERR_RECOVERABLE_RETURN_IF((out_data_buffer == NULL), false, "Data buffer is null"); 00098 cb_type = data_cb->type; 00099 00100 switch (cb_type) { 00101 case CN_CBOR_TAG: 00102 *out_data_buffer = (uint8_t*)data_cb->first_child->v.bytes; 00103 *out_size = (size_t)data_cb->first_child->length; 00104 break; 00105 case CN_CBOR_TEXT: 00106 case CN_CBOR_BYTES: 00107 *out_data_buffer = (uint8_t*)data_cb->v.bytes; 00108 *out_size = (size_t)(data_cb->length); 00109 break; 00110 case CN_CBOR_UINT: 00111 *out_data_buffer = (uint8_t*)(&(data_cb->v.uint)); 00112 *out_size = (size_t)(data_cb->length); 00113 break; 00114 case CN_CBOR_INT: 00115 *out_data_buffer = (uint8_t*)(&(data_cb->v.sint)); 00116 *out_size = (size_t)(data_cb->length); 00117 break; 00118 default: 00119 SA_PV_LOG_ERR("Invalid cbor data type (%u)!", data_cb->type); 00120 return false; 00121 } 00122 SA_PV_LOG_TRACE_FUNC_EXIT("out_size=%" PRIu32 "", (uint32_t)*out_size); 00123 return true; 00124 } 00125 /** Frees all allocated memory of data parameter struct and sets initial values. 00126 * 00127 * @param data_param[in/out] The data parameter structure 00128 */ 00129 void fcc_bundle_clean_and_free_data_param(fcc_bundle_data_param_s *data_param) 00130 { 00131 SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS(); 00132 00133 if (data_param->name != NULL) { 00134 fcc_free(data_param->name); 00135 data_param->name = NULL; 00136 } 00137 00138 data_param->array_cn = NULL; 00139 00140 //FIXME - in case we will support pem, add additional pointer data_der, that will point to allocated 00141 // memory and will always released in case not NULL nad data pointer will relate to user buffer allways. 00142 /*if (data_param->data_der != NULL) { 00143 fcc_stats_free(data_param->data_der); 00144 data_param->data_der = NULL; 00145 }*/ 00146 00147 memset(data_param, 0, sizeof(fcc_bundle_data_param_s)); 00148 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00149 00150 } 00151 bool fcc_bundle_get_data_param(const cn_cbor *data_param_cb, fcc_bundle_data_param_s *data_param) 00152 { 00153 bool status = false; 00154 int data_param_index = 0; 00155 cn_cbor *data_param_value_cb; 00156 fcc_bundle_data_param_type_e data_param_type; 00157 00158 SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS(); 00159 00160 //Prepare key struct 00161 fcc_bundle_clean_and_free_data_param(data_param); 00162 00163 //Go over all key's parameters and extract it to appropriate key struct member 00164 for (data_param_index = FCC_BUNDLE_DATA_PARAM_NAME_TYPE; data_param_index < FCC_BUNDLE_DATA_PARAM_MAX_TYPE; data_param_index++) { 00165 00166 //Get value of parameter 00167 data_param_value_cb = cn_cbor_mapget_string(data_param_cb, fcc_bundle_data_param_lookup_table[data_param_index].data_param_name); 00168 00169 if (data_param_value_cb != NULL) { 00170 //Get type of parameter 00171 data_param_type = fcc_bundle_data_param_lookup_table[data_param_index].data_param_type; 00172 00173 switch (data_param_type) { 00174 00175 case FCC_BUNDLE_DATA_PARAM_NAME_TYPE: 00176 status = get_data_name(data_param_value_cb, &(data_param->name), &(data_param->name_len)); 00177 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != true), status = false, error_exit, "Failed to get data parameter name"); 00178 break; 00179 00180 case FCC_BUNDLE_DATA_PARAM_SCHEME_TYPE: 00181 status = fcc_bundle_get_key_type(data_param_value_cb, (fcc_bundle_key_type_e*)&(data_param->type)); 00182 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != true), status = false, error_exit, "Failed to get parameter type"); 00183 break; 00184 00185 case FCC_BUNDLE_DATA_PARAM_FORMAT_TYPE: 00186 status = get_data_format(data_param_value_cb, (fcc_bundle_data_format_e*)&(data_param->format)); 00187 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != true), status = false, error_exit, "Failed to get key format"); 00188 break; 00189 00190 case FCC_BUNDLE_DATA_PARAM_DATA_TYPE: 00191 status = get_data_buffer_from_cbor(data_param_value_cb, &(data_param->data), &(data_param->data_size)); 00192 data_param->data_type = FCC_EXTERNAL_BUFFER_TYPE; 00193 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != true), status = false, error_exit, "Failed to get parameter data"); 00194 break; 00195 case FCC_BUNDLE_DATA_PARAM_ARRAY_TYPE: 00196 data_param->array_cn = data_param_value_cb; 00197 break; 00198 case FCC_BUNDLE_DATA_PARAM_ACL_TYPE: 00199 status = get_data_buffer_from_cbor(data_param_value_cb, &(data_param->acl), &data_param->acl_size); 00200 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != true), status = false, error_exit, "Failed to get acl data"); 00201 break; 00202 default: 00203 SA_PV_ERR_RECOVERABLE_GOTO_IF((true), status = false, error_exit, "Parameter's field name is illegal"); 00204 }//switch 00205 }//if 00206 }//for 00207 00208 //FIXME: should be uncommented if PEM format is supported. 00209 /* 00210 if (data_param->format == FCC_PEM_DATA_FORMAT) { 00211 //status = convert_certificate_from_pem_to_der((uint8_t**)&(data_param->data), &(data_param->data_size)); 00212 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != true), status = false, error_exit, "Failed to convert the key from pem to der"); 00213 //key->data_type = FCC_INTERNAL_BUFFER_TYPE; 00214 } 00215 */ 00216 00217 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00218 return status; 00219 00220 error_exit: 00221 fcc_bundle_clean_and_free_data_param(data_param); 00222 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00223 return false; 00224 } 00225 00226 fcc_status_e fcc_bundle_process_sotp_buffer(cn_cbor *cbor_bytes, sotp_type_e sotp_type) 00227 { 00228 uint8_t *buf; 00229 size_t buf_size; 00230 fcc_status_e fcc_status = FCC_STATUS_SUCCESS; 00231 bool status; 00232 char *sotp_type_name; 00233 size_t sotp_type_name_size = 0; 00234 00235 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS(); 00236 00237 fcc_status = fcc_get_sotp_type_name(sotp_type, &sotp_type_name, &sotp_type_name_size); 00238 SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status = FCC_STATUS_INVALID_PARAMETER,exit, "Failed to get sotp type name"); 00239 SA_PV_ERR_RECOVERABLE_GOTO_IF((cbor_bytes->type != CN_CBOR_BYTES), fcc_status = FCC_STATUS_BUNDLE_ERROR, exit, "cn_cbor object of incorrect type"); 00240 00241 status = get_data_buffer_from_cbor(cbor_bytes, &buf, &buf_size); 00242 SA_PV_ERR_RECOVERABLE_GOTO_IF((status == false), fcc_status = FCC_STATUS_BUNDLE_ERROR, exit, "Unable to retrieve data from cn_cbor"); 00243 00244 fcc_status = fcc_sotp_data_store(buf, buf_size, sotp_type); 00245 SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status = FCC_STATUS_STORE_ERROR, exit, "Unable to store data to sotp"); 00246 00247 exit: 00248 if (fcc_status != FCC_STATUS_SUCCESS) { 00249 // In case of fcc_store_error_info failure we would still rather return the previous caught error. 00250 (void)fcc_store_error_info((const uint8_t*)sotp_type_name, sotp_type_name_size, fcc_status); 00251 } 00252 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00253 return fcc_status; 00254 } 00255 00256 fcc_status_e bundle_process_status_field(const cn_cbor *cbor_blob, char *cbor_group_name, size_t cbor_group_name_size, bool *fcc_field_status) 00257 { 00258 uint8_t *buff = NULL; 00259 size_t buff_size; 00260 uint32_t fcc_field_value; 00261 bool status; 00262 fcc_status_e fcc_status = FCC_STATUS_SUCCESS; 00263 00264 SA_PV_ERR_RECOVERABLE_GOTO_IF((cbor_blob == NULL), fcc_status = FCC_STATUS_INVALID_PARAMETER, exit, "Invalid param cbor_blob"); 00265 SA_PV_ERR_RECOVERABLE_GOTO_IF((cbor_blob->type != CN_CBOR_UINT), fcc_status = FCC_STATUS_BUNDLE_ERROR, exit, "Unexpected CBOR type"); 00266 00267 status = get_data_buffer_from_cbor(cbor_blob, &buff, &buff_size); 00268 SA_PV_ERR_RECOVERABLE_GOTO_IF((!status), fcc_status = FCC_STATUS_BUNDLE_ERROR, exit, "Unable to retrieve data from cn_cbor"); 00269 SA_PV_ERR_RECOVERABLE_GOTO_IF((buff_size != sizeof(fcc_field_value)), fcc_status = FCC_STATUS_BUNDLE_ERROR, exit, "Incorrect buffer size for field value"); 00270 00271 memcpy(&fcc_field_value, buff, buff_size); 00272 SA_PV_ERR_RECOVERABLE_GOTO_IF(((fcc_field_value != 0) && (fcc_field_value != 1)), fcc_status = FCC_STATUS_BUNDLE_ERROR, exit,"Unexpected value, should be either 0 or 1"); 00273 00274 if (fcc_field_value == 1) { 00275 *fcc_field_status = true; 00276 } 00277 else { 00278 *fcc_field_status = false; 00279 } 00280 00281 exit: 00282 if (fcc_status != FCC_STATUS_SUCCESS) 00283 { 00284 // In case of fcc_store_error_info failure we would still rather return the previous caught error. 00285 (void)fcc_store_error_info((const uint8_t*)cbor_group_name, cbor_group_name_size, fcc_status); 00286 } 00287 return fcc_status; 00288 } 00289 00290 00291 fcc_status_e fcc_bundle_factory_disable( void ) 00292 { 00293 00294 fcc_status_e fcc_status = FCC_STATUS_SUCCESS; 00295 00296 fcc_status = fcc_factory_disable(); 00297 SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status = fcc_status, exit, "Failed to set factory disable flag"); 00298 00299 exit: 00300 if (fcc_status != FCC_STATUS_SUCCESS) { 00301 // In case of fcc_store_error_info failure we would still rather return the previous caught error. 00302 (void)fcc_store_error_info((const uint8_t*)g_sotp_factory_disable_type_name, strlen(g_sotp_factory_disable_type_name), fcc_status); 00303 } 00304 return fcc_status; 00305 }
Generated on Tue Jul 12 2022 19:01:34 by 1.7.2