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.
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 16:24:08 by
1.7.2