Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: FXAS21002 FXOS8700Q
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), (kcm_item_type_e)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. Not deleting anything.", 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 (kcm_item_type_e)item_type); 00102 00103 if (kcm_status != KCM_STATUS_SUCCESS) { 00104 tr_debug("CloudClientStorage::ccs_delete_item [%s] kcm 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 (kcm_item_type_e)item_type, 00124 size_out); 00125 00126 if (kcm_status != KCM_STATUS_SUCCESS) { 00127 tr_debug("CloudClientStorage::ccs_item_size [%s] kcm 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 (kcm_item_type_e)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 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 (kcm_item_type_e)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] 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 return CCS_STATUS_ERROR; 00241 } 00242 00243 00244 kcm_status = kcm_cert_chain_get_next_data((kcm_cert_chain_handle *) chain_handle, (uint8_t*)cert_data, max_size, data_size); 00245 00246 if (kcm_status != KCM_STATUS_SUCCESS) { 00247 tr_error("CloudClientStorage::ccs_get_next_cert_chain - get_next_data error %d", kcm_status); 00248 return CCS_STATUS_ERROR; 00249 } else { 00250 return CCS_STATUS_SUCCESS; 00251 } 00252 } 00253 00254 ccs_status_e ccs_close_certificate_chain(void *chain_handle) 00255 { 00256 kcm_status_e kcm_status; 00257 kcm_cert_chain_handle *handle = (kcm_cert_chain_handle *) chain_handle; 00258 kcm_status = kcm_cert_chain_close(handle); 00259 if (kcm_status != KCM_STATUS_SUCCESS) { 00260 tr_error("CloudClientStorage::ccs_close_certificate_chain - error %d", kcm_status); 00261 return CCS_STATUS_ERROR; 00262 } else { 00263 return CCS_STATUS_SUCCESS; 00264 } 00265 } 00266 00267 ccs_status_e ccs_add_next_cert_chain(void *chain_handle, const uint8_t *cert_data, size_t data_size) 00268 { 00269 kcm_status_e kcm_status; 00270 kcm_status = kcm_cert_chain_add_next((kcm_cert_chain_handle *) chain_handle, cert_data, data_size); 00271 00272 if (kcm_status != KCM_STATUS_SUCCESS) { 00273 tr_error("CloudClientStorage::ccs_add_next_cert_chain - error %d", kcm_status); 00274 return CCS_STATUS_ERROR; 00275 } else { 00276 return CCS_STATUS_SUCCESS; 00277 } 00278 } 00279 00280 ccs_status_e ccs_parse_cert_chain_and_store(const uint8_t *cert_chain_name, 00281 const size_t cert_chain_name_len, 00282 const uint8_t *cert_chain_data, 00283 const uint16_t cert_chain_data_len) 00284 { 00285 assert(cert_chain_data); 00286 assert(cert_chain_data_len > 0); 00287 00288 const uint8_t *ptr = cert_chain_data; 00289 uint8_t version = *ptr++; 00290 uint8_t chain_length = *ptr++; 00291 ccs_status_e success = CCS_STATUS_SUCCESS; 00292 kcm_cert_chain_handle chain_handle; 00293 kcm_status_e status; 00294 00295 // Check overflow 00296 if (ptr - cert_chain_data > cert_chain_data_len) { 00297 success = CCS_STATUS_VALIDATION_FAIL; 00298 } 00299 00300 // Check version is correct and there are certs in the chain 00301 if (version != 1 || chain_length == 0) { 00302 success = CCS_STATUS_VALIDATION_FAIL; 00303 } 00304 00305 // Create KCM cert chain 00306 if (success == CCS_STATUS_SUCCESS) { 00307 status = kcm_cert_chain_create(&chain_handle, 00308 cert_chain_name, 00309 cert_chain_name_len, 00310 chain_length, 00311 false); 00312 tr_debug("Cert chain create %d", status); 00313 if (status != KCM_STATUS_SUCCESS) { 00314 success = CCS_STATUS_ERROR; 00315 } 00316 } 00317 00318 if (success == CCS_STATUS_SUCCESS) { 00319 for (uint8_t i = 0; i < chain_length; i++) { 00320 // Parse certificate length (2 bytes) 00321 uint16_t cert_len = common_read_16_bit(ptr); 00322 ptr += 2; 00323 // Check overflow 00324 if (ptr - cert_chain_data > cert_chain_data_len) { 00325 success = CCS_STATUS_VALIDATION_FAIL; 00326 break; 00327 } 00328 00329 // Store certificate 00330 tr_debug("Storing cert\r\n%s", tr_array(ptr, cert_len)); 00331 status = kcm_cert_chain_add_next(chain_handle, ptr, cert_len); 00332 if (status != KCM_STATUS_SUCCESS) { 00333 success = CCS_STATUS_ERROR; 00334 break; 00335 } 00336 00337 ptr += cert_len; 00338 00339 // Check overflow 00340 if (ptr - cert_chain_data > cert_chain_data_len) { 00341 success = CCS_STATUS_VALIDATION_FAIL; 00342 break; 00343 } 00344 } 00345 00346 status = kcm_cert_chain_close(chain_handle); 00347 if (status != KCM_STATUS_SUCCESS) { 00348 success = CCS_STATUS_ERROR; 00349 } 00350 } 00351 00352 if (success != CCS_STATUS_SUCCESS) { 00353 kcm_cert_chain_delete(cert_chain_name, cert_chain_name_len); 00354 } 00355 00356 return success; 00357 }
Generated on Tue Jul 12 2022 20:20:58 by
