Simulated product dispenser
Fork of mbed-cloud-workshop-connect-HTS221 by
CloudClientStorage.c
00001 // ---------------------------------------------------------------------------- 00002 // Copyright 2016-2017 ARM Ltd. 00003 // 00004 // SPDX-License-Identifier: Apache-2.0 00005 // 00006 // Licensed under the Apache License, Version 2.0 (the "License"); 00007 // you may not use this file except in compliance with the License. 00008 // You may obtain a copy of the License at 00009 // 00010 // http://www.apache.org/licenses/LICENSE-2.0 00011 // 00012 // Unless required by applicable law or agreed to in writing, software 00013 // distributed under the License is distributed on an "AS IS" BASIS, 00014 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00015 // See the License for the specific language governing permissions and 00016 // limitations under the License. 00017 // ---------------------------------------------------------------------------- 00018 00019 #include <string.h> 00020 #include <assert.h> 00021 #include "key_config_manager.h" 00022 #include "CloudClientStorage.h" 00023 #include "mbed-trace/mbed_trace.h" 00024 #include "mbed-client-libservice/common_functions.h" 00025 00026 #define TRACE_GROUP "mClt" 00027 00028 ccs_status_e uninitialize_storage(void) 00029 { 00030 tr_debug("CloudClientStorage::uninitialize_storage"); 00031 00032 kcm_status_e status = kcm_finalize(); 00033 if(status != KCM_STATUS_SUCCESS) { 00034 tr_error("CloudClientStorage::uninitialize_storage - error %d", status); 00035 return CCS_STATUS_ERROR; 00036 } 00037 return CCS_STATUS_SUCCESS; 00038 } 00039 00040 ccs_status_e initialize_storage(void) 00041 { 00042 tr_debug("CloudClientStorage::initialize_storage"); 00043 kcm_status_e status = kcm_init(); 00044 if(status != KCM_STATUS_SUCCESS) { 00045 tr_error("CloudClientStorage::::initialize_storage - error %d", status); 00046 return CCS_STATUS_ERROR; 00047 } 00048 return CCS_STATUS_SUCCESS; 00049 } 00050 00051 ccs_status_e ccs_get_string_item(const char* key, 00052 uint8_t *buffer, 00053 const size_t buffer_size, 00054 ccs_item_type_e item_type) 00055 { 00056 size_t len = 0; 00057 ccs_status_e status = ccs_get_item(key, buffer, buffer_size - 1, &len, item_type); 00058 00059 if (status == CCS_STATUS_SUCCESS) { 00060 // Null terminate after buffer value 00061 buffer[len] = 0; 00062 } 00063 00064 return status; 00065 } 00066 00067 ccs_status_e ccs_check_item(const char* key, ccs_item_type_e item_type) 00068 { 00069 if (key == NULL) { 00070 return CCS_STATUS_ERROR; 00071 } 00072 00073 size_t real_size = 0; 00074 kcm_status_e kcm_status = kcm_item_get_data_size((const uint8_t*)key, strlen(key), item_type, &real_size); 00075 if (kcm_status == KCM_STATUS_ITEM_NOT_FOUND) { 00076 return CCS_STATUS_KEY_DOESNT_EXIST; 00077 } 00078 return CCS_STATUS_SUCCESS; 00079 } 00080 00081 ccs_status_e ccs_delete_item(const char* key, ccs_item_type_e item_type) 00082 { 00083 if (key == NULL) { 00084 tr_error("CloudClientStorage::ccs_delete_item error, invalid parameters"); 00085 return CCS_STATUS_ERROR; 00086 } 00087 00088 ccs_status_e status = ccs_check_item(key, item_type); 00089 if (status == CCS_STATUS_KEY_DOESNT_EXIST) { 00090 // No need to call delete as item does not exist. 00091 tr_debug("CloudClientStorage::ccs_delete_item [%s], type [%d] does not exist.", key, item_type); 00092 return CCS_STATUS_SUCCESS; 00093 } else if (status == CCS_STATUS_ERROR) { 00094 return CCS_STATUS_ERROR; 00095 } 00096 00097 // Delete parameter from storage 00098 tr_debug("CloudClientStorage::ccs_delete_item [%s], type [%d] ", key, item_type); 00099 kcm_status_e kcm_status = kcm_item_delete((const uint8_t*)key, 00100 strlen(key), 00101 item_type); 00102 00103 if (kcm_status != KCM_STATUS_SUCCESS) { 00104 tr_debug("CloudClientStorage::ccs_delete_item [%s] kcm get error %d", key, kcm_status); 00105 return CCS_STATUS_ERROR; 00106 } 00107 00108 return CCS_STATUS_SUCCESS; 00109 } 00110 00111 ccs_status_e ccs_item_size(const char* key, size_t* size_out, ccs_item_type_e item_type) 00112 { 00113 if (key == NULL) { 00114 tr_error("CloudClientStorage::ccs_item_size error, invalid parameters"); 00115 return CCS_STATUS_ERROR; 00116 } 00117 00118 tr_debug("CloudClientStorage::ccs_item_size [%s], item [%d]", key, item_type); 00119 00120 // Get kcm item size 00121 kcm_status_e kcm_status = kcm_item_get_data_size((const uint8_t*)key, 00122 strlen(key), 00123 item_type, 00124 size_out); 00125 00126 if (kcm_status != KCM_STATUS_SUCCESS) { 00127 tr_debug("CloudClientStorage::ccs_item_size [%s] kcm get error %d", key, kcm_status); 00128 return CCS_STATUS_ERROR; 00129 } 00130 00131 return CCS_STATUS_SUCCESS; 00132 } 00133 00134 ccs_status_e ccs_get_item(const char* key, 00135 uint8_t *buffer, 00136 const size_t buffer_size, 00137 size_t *value_length, 00138 ccs_item_type_e item_type) 00139 { 00140 if (key == NULL || buffer == NULL || buffer_size == 0) { 00141 tr_error("CloudClientStorage::ccs_get_item error, invalid parameters"); 00142 return CCS_STATUS_ERROR; 00143 } 00144 00145 tr_debug("CloudClientStorage::ccs_get_item [%s], type [%d]", key, item_type); 00146 00147 kcm_status_e kcm_status = kcm_item_get_data((const uint8_t*)key, 00148 strlen(key), 00149 item_type, 00150 buffer, 00151 buffer_size, 00152 value_length); 00153 00154 if (kcm_status != KCM_STATUS_SUCCESS) { 00155 tr_debug("CloudClientStorage::ccs_get_item [%s] kcm get error %d", key, kcm_status); 00156 return CCS_STATUS_ERROR; 00157 } 00158 00159 return CCS_STATUS_SUCCESS; 00160 } 00161 00162 ccs_status_e ccs_set_item(const char* key, 00163 const uint8_t *buffer, 00164 const size_t buffer_size, 00165 ccs_item_type_e item_type) 00166 { 00167 if (key == NULL || buffer == NULL || buffer_size == 0) { 00168 tr_error("CloudClientStorage::ccs_set_item error, invalid parameters"); 00169 return CCS_STATUS_ERROR; 00170 } 00171 00172 tr_debug("CloudClientStorage::ccs_set_item kcm [%s], type [%d]", key, item_type); 00173 00174 kcm_status_e kcm_status = kcm_item_store((const uint8_t*)key, 00175 strlen(key), 00176 item_type, 00177 false, 00178 buffer, 00179 buffer_size, 00180 NULL); 00181 00182 if (kcm_status == KCM_CRYPTO_STATUS_PRIVATE_KEY_VERIFICATION_FAILED) { 00183 tr_error("CloudClientStorage::ccs_set_item kcm validation error"); 00184 return CCS_STATUS_VALIDATION_FAIL; 00185 } 00186 else if (kcm_status != KCM_STATUS_SUCCESS) { 00187 tr_debug("CloudClientStorage::ccs_set_item kcm [%s] get error %d", key, kcm_status); 00188 return CCS_STATUS_ERROR; 00189 } 00190 00191 return CCS_STATUS_SUCCESS; 00192 } 00193 00194 void *ccs_create_certificate_chain(const char *chain_file_name, size_t chain_len) 00195 { 00196 kcm_status_e kcm_status; 00197 kcm_cert_chain_handle chain_handle; 00198 00199 kcm_status = kcm_cert_chain_create(&chain_handle, 00200 (uint8_t*)chain_file_name, 00201 strlen(chain_file_name), 00202 chain_len, 00203 false); 00204 00205 if (kcm_status != KCM_STATUS_SUCCESS) { 00206 tr_error("CloudClientStorage::ccs_create_certificate_chain - error %d", kcm_status); 00207 return NULL; 00208 } else { 00209 return (void*)chain_handle; 00210 } 00211 } 00212 00213 void *ccs_open_certificate_chain(const char *chain_file_name, size_t *chain_size) 00214 { 00215 kcm_status_e kcm_status; 00216 kcm_cert_chain_handle handle; 00217 00218 kcm_status = kcm_cert_chain_open(&handle, 00219 (uint8_t*)chain_file_name, 00220 strlen(chain_file_name), 00221 chain_size); 00222 00223 if (kcm_status == KCM_STATUS_SUCCESS) { 00224 return (void*)handle; 00225 } else { 00226 tr_error("CloudClientStorage::ccs_open_certificate_chain - error %d", kcm_status); 00227 return NULL; 00228 } 00229 } 00230 00231 ccs_status_e ccs_get_next_cert_chain(void *chain_handle, void *cert_data, size_t *data_size) 00232 { 00233 kcm_status_e kcm_status; 00234 size_t max_size = 1024; 00235 00236 kcm_status = kcm_cert_chain_get_next_size((kcm_cert_chain_handle *) chain_handle, data_size); 00237 00238 if (kcm_status != KCM_STATUS_SUCCESS) { 00239 tr_error("CloudClientStorage::ccs_get_next_cert_chain - get_next_size error %d", kcm_status); 00240 data_size = 0; 00241 return CCS_STATUS_ERROR; 00242 } 00243 00244 00245 kcm_status = kcm_cert_chain_get_next_data((kcm_cert_chain_handle *) chain_handle, (uint8_t*)cert_data, max_size, data_size); 00246 00247 if (kcm_status != KCM_STATUS_SUCCESS) { 00248 tr_error("CloudClientStorage::ccs_get_next_cert_chain - get_next_data error %d", kcm_status); 00249 data_size = 0; 00250 return CCS_STATUS_ERROR; 00251 } else { 00252 return CCS_STATUS_SUCCESS; 00253 } 00254 } 00255 00256 ccs_status_e ccs_close_certificate_chain(void *chain_handle) 00257 { 00258 kcm_status_e kcm_status; 00259 kcm_cert_chain_handle *handle = (kcm_cert_chain_handle *) chain_handle; 00260 kcm_status = kcm_cert_chain_close(handle); 00261 if (kcm_status != KCM_STATUS_SUCCESS) { 00262 tr_error("CloudClientStorage::ccs_close_certificate_chain - error %d", kcm_status); 00263 return CCS_STATUS_ERROR; 00264 } else { 00265 return CCS_STATUS_SUCCESS; 00266 } 00267 } 00268 00269 ccs_status_e ccs_add_next_cert_chain(void *chain_handle, const uint8_t *cert_data, size_t data_size) 00270 { 00271 kcm_status_e kcm_status; 00272 kcm_status = kcm_cert_chain_add_next((kcm_cert_chain_handle *) chain_handle, cert_data, data_size); 00273 00274 if (kcm_status != KCM_STATUS_SUCCESS) { 00275 tr_error("CloudClientStorage::ccs_add_next_cert_chain - error %d", kcm_status); 00276 return CCS_STATUS_ERROR; 00277 } else { 00278 return CCS_STATUS_SUCCESS; 00279 } 00280 } 00281 00282 ccs_status_e ccs_parse_cert_chain_and_store(const uint8_t *cert_chain_name, 00283 const size_t cert_chain_name_len, 00284 const uint8_t *cert_chain_data, 00285 const uint16_t cert_chain_data_len) 00286 { 00287 assert(cert_chain_data); 00288 assert(cert_chain_data_len > 0); 00289 00290 const uint8_t *ptr = cert_chain_data; 00291 uint8_t version = *ptr++; 00292 uint8_t chain_length = *ptr++; 00293 ccs_status_e success = CCS_STATUS_SUCCESS; 00294 kcm_cert_chain_handle chain_handle; 00295 kcm_status_e status = KCM_STATUS_ERROR; 00296 00297 // Check overflow 00298 if (ptr - cert_chain_data > cert_chain_data_len) { 00299 success = CCS_STATUS_VALIDATION_FAIL; 00300 } 00301 00302 // Check version is correct and there are certs in the chain 00303 if (version != 1 || chain_length == 0) { 00304 success = CCS_STATUS_VALIDATION_FAIL; 00305 } 00306 00307 // Create KCM cert chain 00308 if (success == CCS_STATUS_SUCCESS) { 00309 status = kcm_cert_chain_create(&chain_handle, 00310 cert_chain_name, 00311 cert_chain_name_len, 00312 chain_length, 00313 false); 00314 tr_debug("Cert chain create %d", status); 00315 if (status != KCM_STATUS_SUCCESS) { 00316 success = CCS_STATUS_ERROR; 00317 } 00318 } 00319 00320 if (success == CCS_STATUS_SUCCESS) { 00321 for (uint8_t i = 0; i < chain_length; i++) { 00322 // Parse certificate length (2 bytes) 00323 uint16_t cert_len = common_read_16_bit(ptr); 00324 ptr += 2; 00325 // Check overflow 00326 if (ptr - cert_chain_data > cert_chain_data_len) { 00327 success = CCS_STATUS_VALIDATION_FAIL; 00328 break; 00329 } 00330 00331 // Store certificate 00332 tr_debug("Storing cert\r\n%s", tr_array(ptr, cert_len)); 00333 status = kcm_cert_chain_add_next(chain_handle, ptr, cert_len); 00334 if (status != KCM_STATUS_SUCCESS) { 00335 success = CCS_STATUS_ERROR; 00336 break; 00337 } 00338 00339 ptr += cert_len; 00340 00341 // Check overflow 00342 if (ptr - cert_chain_data > cert_chain_data_len) { 00343 success = CCS_STATUS_VALIDATION_FAIL; 00344 break; 00345 } 00346 } 00347 } 00348 00349 status = kcm_cert_chain_close(chain_handle); 00350 if (status != KCM_STATUS_SUCCESS) { 00351 success = CCS_STATUS_ERROR; 00352 } 00353 00354 if (success != CCS_STATUS_SUCCESS) { 00355 kcm_cert_chain_delete(cert_chain_name, cert_chain_name_len); 00356 } 00357 00358 return success; 00359 }
Generated on Tue Jul 12 2022 19:12:11 by 1.7.2