Simulated product dispenser
Fork of mbed-cloud-workshop-connect-HTS221 by
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 #ifndef USE_TINY_CBOR 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 if (data_param->private_key_name != NULL) { 00139 fcc_free(data_param->private_key_name); 00140 data_param->private_key_name = NULL; 00141 } 00142 00143 data_param->array_cn = NULL; 00144 00145 //FIXME - in case we will support pem, add additional pointer data_der, that will point to allocated 00146 // memory and will always released in case not NULL nad data pointer will relate to user buffer allways. 00147 /*if (data_param->data_der != NULL) { 00148 fcc_stats_free(data_param->data_der); 00149 data_param->data_der = NULL; 00150 }*/ 00151 00152 memset(data_param, 0, sizeof(fcc_bundle_data_param_s)); 00153 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00154 00155 } 00156 bool fcc_bundle_get_data_param(const cn_cbor *data_param_cb, fcc_bundle_data_param_s *data_param) 00157 { 00158 bool status = false; 00159 int data_param_index = 0; 00160 cn_cbor *data_param_value_cb; 00161 fcc_bundle_data_param_type_e data_param_type; 00162 00163 SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS(); 00164 00165 //Prepare key struct 00166 fcc_bundle_clean_and_free_data_param(data_param); 00167 00168 //Go over all key's parameters and extract it to appropriate key struct member 00169 for (data_param_index = FCC_BUNDLE_DATA_PARAM_NAME_TYPE; data_param_index < FCC_BUNDLE_DATA_PARAM_MAX_TYPE; data_param_index++) { 00170 00171 //Get value of parameter 00172 data_param_value_cb = cn_cbor_mapget_string(data_param_cb, fcc_bundle_data_param_lookup_table[data_param_index].data_param_name); 00173 00174 if (data_param_value_cb != NULL) { 00175 //Get type of parameter 00176 data_param_type = fcc_bundle_data_param_lookup_table[data_param_index].data_param_type; 00177 00178 switch (data_param_type) { 00179 case FCC_BUNDLE_DATA_PARAMETER_PRIVATE_KEY_NAME_TYPE: 00180 status = get_data_name(data_param_value_cb, &(data_param->private_key_name), &(data_param->private_key_name_len)); 00181 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != true), status = false, error_exit, "Failed to get private key name"); 00182 break; 00183 00184 case FCC_BUNDLE_DATA_PARAM_NAME_TYPE: 00185 status = get_data_name(data_param_value_cb, &(data_param->name), &(data_param->name_len)); 00186 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != true), status = false, error_exit, "Failed to get data parameter name"); 00187 break; 00188 00189 case FCC_BUNDLE_DATA_PARAM_SCHEME_TYPE: 00190 status = fcc_bundle_get_key_type(data_param_value_cb, (fcc_bundle_key_type_e*)&(data_param->type)); 00191 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != true), status = false, error_exit, "Failed to get parameter type"); 00192 break; 00193 00194 case FCC_BUNDLE_DATA_PARAM_FORMAT_TYPE: 00195 status = get_data_format(data_param_value_cb, (fcc_bundle_data_format_e*)&(data_param->format)); 00196 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != true), status = false, error_exit, "Failed to get key format"); 00197 break; 00198 00199 case FCC_BUNDLE_DATA_PARAM_DATA_TYPE: 00200 status = get_data_buffer_from_cbor(data_param_value_cb, &(data_param->data), &(data_param->data_size)); 00201 data_param->data_type = FCC_EXTERNAL_BUFFER_TYPE; 00202 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != true), status = false, error_exit, "Failed to get parameter data"); 00203 break; 00204 case FCC_BUNDLE_DATA_PARAM_ARRAY_TYPE: 00205 data_param->array_cn = data_param_value_cb; 00206 break; 00207 case FCC_BUNDLE_DATA_PARAM_ACL_TYPE: 00208 status = get_data_buffer_from_cbor(data_param_value_cb, &(data_param->acl), &data_param->acl_size); 00209 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != true), status = false, error_exit, "Failed to get acl data"); 00210 break; 00211 default: 00212 SA_PV_ERR_RECOVERABLE_GOTO_IF((true), status = false, error_exit, "Parameter's field name is illegal"); 00213 }//switch 00214 }//if 00215 }//for 00216 00217 //FIXME: should be uncommented if PEM format is supported. 00218 /* 00219 if (data_param->format == FCC_PEM_DATA_FORMAT) { 00220 //status = convert_certificate_from_pem_to_der((uint8_t**)&(data_param->data), &(data_param->data_size)); 00221 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != true), status = false, error_exit, "Failed to convert the key from pem to der"); 00222 //key->data_type = FCC_INTERNAL_BUFFER_TYPE; 00223 } 00224 */ 00225 00226 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00227 return status; 00228 00229 error_exit: 00230 fcc_bundle_clean_and_free_data_param(data_param); 00231 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00232 return false; 00233 } 00234 00235 fcc_status_e fcc_bundle_process_sotp_buffer(cn_cbor *cbor_bytes, sotp_type_e sotp_type) 00236 { 00237 uint8_t *buf; 00238 size_t buf_size; 00239 fcc_status_e fcc_status = FCC_STATUS_SUCCESS; 00240 bool status; 00241 char *sotp_type_name; 00242 size_t sotp_type_name_size = 0; 00243 00244 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS(); 00245 00246 fcc_status = fcc_get_sotp_type_name(sotp_type, &sotp_type_name, &sotp_type_name_size); 00247 SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status = FCC_STATUS_INVALID_PARAMETER,exit, "Failed to get sotp type name"); 00248 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"); 00249 00250 status = get_data_buffer_from_cbor(cbor_bytes, &buf, &buf_size); 00251 SA_PV_ERR_RECOVERABLE_GOTO_IF((status == false), fcc_status = FCC_STATUS_BUNDLE_ERROR, exit, "Unable to retrieve data from cn_cbor"); 00252 00253 fcc_status = fcc_sotp_data_store(buf, buf_size, sotp_type); 00254 SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status = FCC_STATUS_STORE_ERROR, exit, "Unable to store data to sotp"); 00255 00256 exit: 00257 if (fcc_status != FCC_STATUS_SUCCESS) { 00258 // In case of fcc_store_error_info failure we would still rather return the previous caught error. 00259 (void)fcc_store_error_info((const uint8_t*)sotp_type_name, sotp_type_name_size, fcc_status); 00260 } 00261 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00262 return fcc_status; 00263 } 00264 00265 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) 00266 { 00267 uint8_t *buff = NULL; 00268 size_t buff_size; 00269 uint32_t fcc_field_value; 00270 bool status; 00271 fcc_status_e fcc_status = FCC_STATUS_SUCCESS; 00272 00273 SA_PV_ERR_RECOVERABLE_GOTO_IF((cbor_blob == NULL), fcc_status = FCC_STATUS_INVALID_PARAMETER, exit, "Invalid param cbor_blob"); 00274 SA_PV_ERR_RECOVERABLE_GOTO_IF((cbor_blob->type != CN_CBOR_UINT), fcc_status = FCC_STATUS_BUNDLE_ERROR, exit, "Unexpected CBOR type"); 00275 00276 status = get_data_buffer_from_cbor(cbor_blob, &buff, &buff_size); 00277 SA_PV_ERR_RECOVERABLE_GOTO_IF((!status), fcc_status = FCC_STATUS_BUNDLE_ERROR, exit, "Unable to retrieve data from cn_cbor"); 00278 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"); 00279 00280 memcpy(&fcc_field_value, buff, buff_size); 00281 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"); 00282 00283 if (fcc_field_value == 1) { 00284 *fcc_field_status = true; 00285 } 00286 else { 00287 *fcc_field_status = false; 00288 } 00289 00290 exit: 00291 if (fcc_status != FCC_STATUS_SUCCESS) 00292 { 00293 // In case of fcc_store_error_info failure we would still rather return the previous caught error. 00294 (void)fcc_store_error_info((const uint8_t*)cbor_group_name, cbor_group_name_size, fcc_status); 00295 } 00296 return fcc_status; 00297 } 00298 00299 00300 fcc_status_e fcc_bundle_factory_disable( void ) 00301 { 00302 00303 fcc_status_e fcc_status = FCC_STATUS_SUCCESS; 00304 00305 fcc_status = fcc_factory_disable(); 00306 SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status = fcc_status, exit, "Failed to set factory disable flag"); 00307 00308 exit: 00309 if (fcc_status != FCC_STATUS_SUCCESS) { 00310 // In case of fcc_store_error_info failure we would still rather return the previous caught error. 00311 (void)fcc_store_error_info((const uint8_t*)g_sotp_factory_disable_type_name, strlen(g_sotp_factory_disable_type_name), fcc_status); 00312 } 00313 return fcc_status; 00314 } 00315 #endif
Generated on Tue Jul 12 2022 19:12:12 by 1.7.2