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), (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 Mon Aug 29 2022 19:53:38 by
