Mayank Gupta / Mbed OS pelion-example-frdm

Dependencies:   FXAS21002 FXOS8700Q

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ce_safe_renewal_internal.c Source File

ce_safe_renewal_internal.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 #include <stdbool.h>
00017 #include "key_config_manager.h"
00018 #include "pv_error_handling.h"
00019 #include "storage.h"
00020 #include "fcc_malloc.h"
00021 #include "pv_macros.h"
00022 #include "ce_internal.h"
00023 #include "est_defs.h"
00024 #include "storage.h"
00025 
00026 const char g_lwm2m_name[] = "LWM2M";
00027 const char g_renewal_status_file[] = "renewal_status";
00028 
00029 extern const char g_fcc_lwm2m_device_certificate_name[];
00030 extern const char g_fcc_lwm2m_device_private_key_name[];
00031 
00032 /* The function reads item from storage according to its kcm  and source type, 
00033 the function allocated buffer for the item*/
00034 kcm_status_e  ce_get_kcm_data(const uint8_t *parameter_name, 
00035     size_t size_of_parameter_name,
00036     kcm_item_type_e kcm_type,
00037     kcm_data_source_type_e data_source_type,
00038     uint8_t **kcm_data,
00039     size_t *kcm_data_size)
00040 {
00041 
00042     kcm_status_e  kcm_status = KCM_STATUS_SUCCESS;
00043 
00044     SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS();
00045     SA_PV_ERR_RECOVERABLE_RETURN_IF((parameter_name == NULL), kcm_status = KCM_STATUS_INVALID_PARAMETER, "Wrong parameter_name pointer");
00046     SA_PV_ERR_RECOVERABLE_RETURN_IF((size_of_parameter_name == 0), kcm_status = KCM_STATUS_INVALID_PARAMETER, "Wrong parameter_name size.");
00047     SA_PV_ERR_RECOVERABLE_RETURN_IF((*kcm_data != NULL), kcm_status = KCM_STATUS_INVALID_PARAMETER, "Wrong *kcm_data pointer, should be NULL");
00048     SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_data_size == NULL), kcm_status = KCM_STATUS_INVALID_PARAMETER, "Wrong kcm_data_size pointer.");
00049 
00050     //Get size of kcm data
00051     kcm_status = storage_data_size_read(parameter_name,
00052         size_of_parameter_name,
00053         kcm_type,
00054         data_source_type,
00055         kcm_data_size);
00056     if (kcm_status == KCM_STATUS_ITEM_NOT_FOUND) {
00057         return kcm_status;
00058     }
00059     SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed to get kcm data size");
00060     SA_PV_ERR_RECOVERABLE_RETURN_IF((*kcm_data_size == 0), kcm_status = KCM_STATUS_ITEM_IS_EMPTY, "KCM item is empty");
00061 
00062     //Allocate memory and get device certificate data
00063     *kcm_data = fcc_malloc(*kcm_data_size);
00064     SA_PV_ERR_RECOVERABLE_RETURN_IF((*kcm_data == NULL), kcm_status = KCM_STATUS_OUT_OF_MEMORY, "Failed to allocate buffer for kcm data");
00065 
00066     kcm_status = storage_data_read(parameter_name, size_of_parameter_name, kcm_type, data_source_type, *kcm_data, *kcm_data_size, kcm_data_size);
00067     SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status = kcm_status, exit, "Failed to get device certificate data");
00068 
00069 exit:
00070     if (kcm_status != KCM_STATUS_SUCCESS) {
00071         fcc_free(*kcm_data);
00072         *kcm_data = NULL;
00073     }
00074     SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS();
00075     return kcm_status;
00076 }
00077 /*The function copies certificate chain or single certificate from source  to destination (inside storage)*/
00078 static kcm_status_e  copy_certificate_chain(const uint8_t *item_name, size_t item_name_len, kcm_data_source_type_e source_type, kcm_data_source_type_e destination_type)
00079 {
00080     kcm_status_e  kcm_status = KCM_STATUS_SUCCESS;
00081     uint8_t *item_data = NULL;
00082     size_t item_data_len = 0;
00083     kcm_cert_chain_handle kcm_source_chain_handle;
00084     kcm_cert_chain_handle kcm_destination_chain_handle;
00085     size_t kcm_chain_len_out = 0;
00086     size_t  kcm_actual_cert_data_size = 0;
00087     int cert_index = 0;
00088     kcm_cert_chain_context_int_s *chain_context;
00089 
00090     //Open chain 
00091     kcm_status = storage_cert_chain_open(&kcm_source_chain_handle, item_name, item_name_len, source_type, &kcm_chain_len_out);
00092     SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed to open chain");
00093     SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_chain_len_out == 0), kcm_status = KCM_STATUS_INVALID_NUM_OF_CERT_IN_CHAIN, exit, "Invalid kcm_chain_len_out");
00094 
00095     chain_context = (kcm_cert_chain_context_int_s*)kcm_source_chain_handle;
00096 
00097     //Current item is a single certificate 
00098     if (chain_context->is_meta_data == false && kcm_chain_len_out == 1) {
00099         //Read the item from source 
00100         kcm_status = ce_get_kcm_data(item_name, item_name_len, KCM_CERTIFICATE_ITEM, source_type, &item_data, &item_data_len);
00101         SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status = kcm_status, exit, "Failed to get item data");
00102 
00103         //Save the item as backup item
00104         kcm_status = storage_data_write(item_name, item_name_len, KCM_CERTIFICATE_ITEM, false, destination_type, item_data, item_data_len );
00105         SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status = kcm_status, exit, "Failed to copy item data");
00106     }  else {
00107         //Current item is certificate chian
00108         for (cert_index = 1; cert_index <= (int)kcm_chain_len_out; cert_index++)
00109         {
00110 
00111             //Create destination chain for start
00112             if (cert_index == 1) {
00113                 kcm_status = storage_cert_chain_create(&kcm_destination_chain_handle, item_name, item_name_len, kcm_chain_len_out, false, destination_type);
00114                 SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status = kcm_status, exit, "Failed to create destination chain");
00115             }
00116             //Get next certificate data size from source chain
00117             kcm_status = storage_cert_chain_get_next_size(kcm_source_chain_handle, source_type, &item_data_len);
00118             SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status = kcm_status, exit_and_close, "Failed to _kcm_cert_chain_get_next_sizen");
00119 
00120             //Allocate memory and get  certificate data from source chain
00121             item_data = fcc_malloc(item_data_len);
00122             SA_PV_ERR_RECOVERABLE_GOTO_IF((item_data == NULL), kcm_status = KCM_STATUS_OUT_OF_MEMORY, exit_and_close, "Failed to allocate buffer for kcm data");
00123 
00124             //Get next certificate data
00125             kcm_status = storage_cert_chain_get_next_data(kcm_source_chain_handle, item_data, item_data_len, source_type, &kcm_actual_cert_data_size);
00126             SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status = kcm_status, exit_and_close, "Failed to get certificate kcm data");
00127             SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_actual_cert_data_size != item_data_len), kcm_status = kcm_status, exit_and_close, "Wrong certificate data size");
00128 
00129             //Add the data to destination chain
00130             kcm_status = storage_chain_add_next(kcm_destination_chain_handle, item_data, item_data_len, destination_type);
00131             SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status = kcm_status, exit_and_close, "Failed to add data to chain");
00132 
00133             //free allocated buffer
00134             fcc_free(item_data);
00135             item_data = NULL;
00136         }
00137         //Close destination chain
00138 exit_and_close:
00139         kcm_status = storage_cert_chain_close(kcm_destination_chain_handle, destination_type);
00140          SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status = kcm_status, exit,"Failed to close destination chain");
00141 
00142     }
00143 
00144 exit:
00145         if (item_data != NULL) {
00146             fcc_free(item_data);
00147         }
00148         //close source chain
00149         kcm_status = storage_cert_chain_close(kcm_source_chain_handle, source_type);
00150         SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed to close source chain");
00151 
00152         return kcm_status;
00153 
00154 }
00155 static kcm_status_e  copy_kcm_item(const uint8_t *item_name, size_t item_name_len, kcm_item_type_e kcm_type, kcm_data_source_type_e source_type, kcm_data_source_type_e destination_type)
00156 {
00157 
00158     kcm_status_e  kcm_status = KCM_STATUS_SUCCESS;
00159     uint8_t *item_data = NULL;
00160     size_t item_data_len = 0;
00161 
00162     //Read the data
00163     if (kcm_type == KCM_CERTIFICATE_ITEM) {
00164 
00165         //copy certificate chain 
00166         kcm_status = copy_certificate_chain(item_name, item_name_len, source_type, destination_type);
00167         SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed to copy chain");
00168     }  else { //not certificate
00169         //Read the item from source 
00170         kcm_status = ce_get_kcm_data(item_name, item_name_len, kcm_type, source_type, &item_data, &item_data_len);
00171         SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed to get item data");
00172 
00173         //Save the item as backup item
00174         kcm_status = storage_data_write(item_name, item_name_len, kcm_type, false, destination_type,item_data, item_data_len );
00175         SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status = kcm_status, exit, "Failed to copy item data");
00176     }
00177 
00178 exit:
00179     if (item_data != NULL) {
00180         fcc_free(item_data);
00181     }
00182     return kcm_status;
00183 
00184 }
00185 
00186 bool ce_set_item_names(const char *item_name, char **private_key_name_out, char **public_key_name_out, char **certificate_name_out)
00187 {
00188     SA_PV_ERR_RECOVERABLE_RETURN_IF((item_name == NULL), false, "Invalid item_name");
00189     SA_PV_ERR_RECOVERABLE_RETURN_IF((private_key_name_out == NULL), false, "Invalid private_key_name");
00190     SA_PV_ERR_RECOVERABLE_RETURN_IF((certificate_name_out == NULL), false, "Invalid certificate");
00191     // public key may be NULL - don't bother to check pointer
00192 
00193     if (pv_str_equals(item_name, g_lwm2m_name, (uint32_t)(strlen(item_name) + 1)) == true) {
00194         *private_key_name_out = (char*)g_fcc_lwm2m_device_private_key_name;
00195         *certificate_name_out = (char*)g_fcc_lwm2m_device_certificate_name;
00196         if (public_key_name_out != NULL) {
00197             *public_key_name_out = NULL;
00198         }
00199     } else {
00200         *private_key_name_out = (char*)item_name;
00201         *certificate_name_out = (char*)item_name;
00202         if (public_key_name_out != NULL) {
00203             *public_key_name_out = (char*)item_name;
00204         }
00205     }
00206     return true;
00207 }
00208 
00209 static kcm_status_e  check_items_existence(const char *item_name, kcm_data_source_type_e source_type, bool *is_public_key)
00210 {
00211     kcm_status_e  kcm_status = KCM_STATUS_SUCCESS;
00212     kcm_cert_chain_handle kcm_source_chain_handle;
00213     size_t kcm_data_size = 0;
00214     uint8_t *private_key_name = NULL;
00215     uint8_t *public_key_name = NULL;
00216     uint8_t *certificate_name = NULL;
00217     bool local_is_public_key = false;
00218 
00219     SA_PV_ERR_RECOVERABLE_RETURN_IF((item_name == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid item_name");
00220     SA_PV_ERR_RECOVERABLE_RETURN_IF(!(ce_set_item_names(item_name, (char**)&private_key_name, (char**)&public_key_name, (char**)&certificate_name)), KCM_STATUS_INVALID_PARAMETER, "Failed to set internal names for items");
00221 
00222     //Check private key
00223     kcm_status = storage_data_size_read((const uint8_t*)private_key_name, (size_t)strlen((char*)private_key_name), KCM_PRIVATE_KEY_ITEM, source_type, &kcm_data_size);
00224     SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed to get private key size");
00225 
00226     if (public_key_name != NULL) {
00227         kcm_status = storage_data_size_read((const uint8_t*)public_key_name, (size_t)strlen((char*)public_key_name), KCM_PUBLIC_KEY_ITEM, source_type, &kcm_data_size);
00228         SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS && kcm_status != KCM_STATUS_ITEM_NOT_FOUND), kcm_status, "Failed to get public key size");
00229 
00230         if (kcm_status == KCM_STATUS_SUCCESS) {
00231             local_is_public_key = true;
00232         }
00233     } 
00234 
00235     kcm_status = storage_cert_chain_open(&kcm_source_chain_handle, (const uint8_t*)certificate_name, strlen((char*)certificate_name), source_type, &kcm_data_size);
00236      SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed to get certificate size");
00237 
00238     kcm_status = storage_cert_chain_close(kcm_source_chain_handle, source_type);
00239     SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed to close source chain");
00240 
00241     *is_public_key = local_is_public_key;
00242     return kcm_status;
00243 
00244 }
00245 /*! The API deletes set of items (key pair and certificate/certificate chain) according to given name and source type.
00246 *    @param[in] item_name                pointer to item name.
00247 *    @param[in] item_name_len            length of item name.
00248 *    @param[in] source_data_type         type of data type to verify (backup or original)
00249 *    @param[in] is_public_key                    flag that indicates if public key exists in the storage.
00250 *    @returns
00251 *        CE_STATUS_SUCCESS in case of success or one of the `::ce_status_e` errors otherwise.
00252 */
00253 kcm_status_e  ce_clean_items(const char *item_name, kcm_data_source_type_e data_source_type, bool is_public_key)
00254 {
00255     kcm_status_e  kcm_status = KCM_STATUS_SUCCESS;
00256     int num_of_failures = 0;
00257     uint8_t *private_key_name = NULL;
00258     uint8_t *public_key_name = NULL;
00259     uint8_t *certificate_name = NULL;
00260 
00261     SA_PV_ERR_RECOVERABLE_RETURN_IF((item_name == NULL), kcm_status = KCM_STATUS_INVALID_PARAMETER, "Invalid item_name");
00262     SA_PV_LOG_INFO_FUNC_ENTER("item name =  %s",  item_name);
00263     SA_PV_ERR_RECOVERABLE_RETURN_IF((data_source_type != KCM_ORIGINAL_ITEM && data_source_type != KCM_BACKUP_ITEM), KCM_STATUS_INVALID_PARAMETER, "Invalid data_source_type");
00264     SA_PV_ERR_RECOVERABLE_RETURN_IF(!(ce_set_item_names(item_name, (char**)&private_key_name, (char**)&public_key_name, (char**)&certificate_name)), KCM_STATUS_INVALID_PARAMETER, "Failed to set internal names for items");
00265 
00266     //Try to delete private key
00267     kcm_status = storage_data_delete((const uint8_t*)private_key_name, strlen((char*)private_key_name), KCM_PRIVATE_KEY_ITEM, data_source_type);
00268     if (kcm_status != KCM_STATUS_SUCCESS && kcm_status != KCM_STATUS_ITEM_NOT_FOUND) {
00269         num_of_failures++;
00270         SA_PV_LOG_ERR("Failed to delete private key");
00271     }
00272 
00273     if (is_public_key == true && public_key_name != NULL)
00274     {
00275         //Try to delete public key
00276         kcm_status = storage_data_delete((const uint8_t*)public_key_name, strlen((char*)public_key_name), KCM_PUBLIC_KEY_ITEM, data_source_type);
00277         if (kcm_status != KCM_STATUS_SUCCESS && kcm_status != KCM_STATUS_ITEM_NOT_FOUND) {
00278             num_of_failures++;
00279             SA_PV_LOG_ERR("Failed to delete public key");
00280         }
00281     }
00282 
00283     //Try to delete certificate/certificate chain
00284     kcm_status = storage_data_delete((const uint8_t*)certificate_name, strlen((char*)certificate_name), KCM_CERTIFICATE_ITEM, data_source_type);
00285     if (kcm_status == KCM_STATUS_ITEM_NOT_FOUND) {//We need to check certificate chain with the same name
00286         kcm_status = storage_cert_chain_delete((const uint8_t*)certificate_name, strlen((char*)certificate_name), data_source_type);
00287     }
00288     if (kcm_status != KCM_STATUS_SUCCESS  && kcm_status != KCM_STATUS_ITEM_NOT_FOUND) {
00289         num_of_failures++;
00290         SA_PV_LOG_ERR("Failed to delete certificate/certificate chain");
00291     }
00292 
00293     SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS();
00294     if (num_of_failures != 0) {
00295         return KCM_STATUS_STORAGE_ERROR;
00296     }
00297     return KCM_STATUS_SUCCESS;
00298 
00299 }
00300 /*! The API creates a copy of renewal items.
00301 *
00302 *    @param[in] item_name                pointer to item name.
00303 *    @param[in] item_name_len           length of item name.
00304 *    @param[in] is_public_key                    flag that indicates if public key exists in the storage.
00305 *
00306 *    @returns
00307 *        CE_STATUS_SUCCESS in case of success or one of the `::ce_status_e` errors otherwise.
00308 */
00309 
00310 kcm_status_e  ce_create_backup_items(const char *item_name, bool is_public_key)
00311 {
00312     kcm_status_e  kcm_status = KCM_STATUS_SUCCESS;
00313     uint8_t *private_key_name = NULL;
00314     uint8_t *public_key_name = NULL;
00315     uint8_t *certificate_name = NULL;
00316 
00317     SA_PV_ERR_RECOVERABLE_RETURN_IF((item_name == NULL), kcm_status = KCM_STATUS_INVALID_PARAMETER, "Invalid item_name");
00318     SA_PV_LOG_INFO_FUNC_ENTER("item name =  %s", item_name);
00319     SA_PV_ERR_RECOVERABLE_RETURN_IF(!(ce_set_item_names(item_name, (char**)&private_key_name, (char**)&public_key_name, (char**)&certificate_name)), KCM_STATUS_INVALID_PARAMETER, "Failed to set internal names for items");
00320 
00321     //Backup private key
00322     kcm_status = copy_kcm_item(private_key_name, strlen((char*)private_key_name), KCM_PRIVATE_KEY_ITEM, KCM_ORIGINAL_ITEM, KCM_BACKUP_ITEM);
00323     SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status = kcm_status, exit,  "Falid to backup private key");
00324 
00325     //Check if public key exists
00326     if (is_public_key == true && public_key_name != NULL) {
00327         //Backup private key
00328         kcm_status = copy_kcm_item(public_key_name, strlen((char*)public_key_name), KCM_PUBLIC_KEY_ITEM, KCM_ORIGINAL_ITEM, KCM_BACKUP_ITEM);
00329         SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status = kcm_status, exit , "Falid to backup public key");
00330     }
00331 
00332     //Backup certificate/certificate chain
00333     kcm_status = copy_kcm_item((const uint8_t*)certificate_name, strlen((char*)certificate_name), KCM_CERTIFICATE_ITEM, KCM_ORIGINAL_ITEM, KCM_BACKUP_ITEM);
00334     SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status = kcm_status, exit , "Falid to backup certificate");
00335 
00336     SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS();
00337 
00338     return kcm_status;
00339 
00340 exit:
00341     //Delete item that was already copied
00342     ce_clean_items(item_name, KCM_BACKUP_ITEM, is_public_key);
00343     return kcm_status;
00344 }
00345 
00346 /*! The API restores backup items and moves it to original source, if the operation succeeded, the backup items deleted.
00347 *    @param[in] item_name                pointer to item name.
00348 *    @param[in] item_name_len            length of item name.
00349 *    @returns
00350 *        CE_STATUS_SUCCESS in case of success or one of the `::ce_status_e` errors otherwise.
00351 */
00352 kcm_status_e  ce_restore_backup_items(const char *item_name)
00353 {
00354     kcm_status_e  kcm_status = KCM_STATUS_SUCCESS;
00355     uint8_t *private_key_name = NULL;
00356     uint8_t *public_key_name = NULL;
00357     uint8_t *certificate_name = NULL;
00358 
00359     bool is_public_key_in_storage = false;
00360 
00361     SA_PV_ERR_RECOVERABLE_RETURN_IF((item_name == NULL), kcm_status = KCM_STATUS_INVALID_PARAMETER, "Invalid item_name");
00362     SA_PV_LOG_INFO_FUNC_ENTER("item name =  %s",item_name);
00363 
00364     //Check first that backup items exists
00365     kcm_status = check_items_existence(item_name, KCM_BACKUP_ITEM, &is_public_key_in_storage);
00366     if (kcm_status == KCM_STATUS_ITEM_NOT_FOUND) {
00367         //One of mandatory backup items is missing -> clean the backup items, do not change original items
00368         ce_clean_items(item_name, KCM_BACKUP_ITEM, true);
00369         return KCM_STATUS_ITEM_NOT_FOUND;
00370     } else {
00371         SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed to verify backup items");
00372     }
00373     SA_PV_ERR_RECOVERABLE_RETURN_IF(!(ce_set_item_names(item_name,(char**)&private_key_name, (char**)&public_key_name, (char**)&certificate_name)), KCM_STATUS_INVALID_PARAMETER, "Failed to set internal names for items");
00374 
00375  
00376     //Clean original items before backup restore
00377     ce_clean_items(item_name, KCM_ORIGINAL_ITEM, true);
00378 
00379     //Restore backup items by copying backup items to original source
00380     kcm_status = copy_kcm_item(private_key_name, strlen((char*)private_key_name), KCM_PRIVATE_KEY_ITEM, KCM_BACKUP_ITEM, KCM_ORIGINAL_ITEM);
00381     SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed to copy backup private key to original source");
00382 
00383     if (is_public_key_in_storage == true && public_key_name != NULL) {
00384         kcm_status = copy_kcm_item(public_key_name, strlen((char*)public_key_name), KCM_PUBLIC_KEY_ITEM, KCM_BACKUP_ITEM, KCM_ORIGINAL_ITEM);
00385         SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed to copy backup public key to original source");
00386     }
00387 
00388     kcm_status = copy_kcm_item(certificate_name, strlen((char*)certificate_name), KCM_CERTIFICATE_ITEM, KCM_BACKUP_ITEM, KCM_ORIGINAL_ITEM);
00389     SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed to copy backup certificate to original source");
00390  
00391     //Clean backup items after it was restored
00392     kcm_status = ce_clean_items(item_name,KCM_BACKUP_ITEM, true);
00393     SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS && kcm_status != KCM_STATUS_ITEM_NOT_FOUND), kcm_status, "Failed to clean backup items");
00394 
00395     SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS();
00396 
00397     return kcm_status;
00398 }
00399 
00400 kcm_status_e  ce_create_renewal_status(const char *item_name)
00401 {
00402     kcm_status_e  kcm_status = KCM_STATUS_SUCCESS;
00403 
00404     SA_PV_ERR_RECOVERABLE_RETURN_IF((item_name == NULL), kcm_status = KCM_STATUS_INVALID_PARAMETER, "Invalid item_name");
00405     SA_PV_LOG_INFO_FUNC_ENTER("item name =  %s", item_name);
00406 
00407     kcm_status = storage_data_write((const uint8_t*)g_renewal_status_file,(size_t)strlen(g_renewal_status_file), KCM_CONFIG_ITEM, false, KCM_BACKUP_ITEM,(const uint8_t*)item_name, (size_t)strlen(item_name));
00408     SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed to create renewal status");
00409 
00410     SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS();
00411 
00412     return KCM_STATUS_SUCCESS;
00413 }
00414 
00415 kcm_status_e  ce_delete_renewal_status(void)
00416 {
00417     kcm_status_e  kcm_status = KCM_STATUS_SUCCESS;
00418 
00419     SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS();
00420 
00421     kcm_status = storage_data_delete((const uint8_t*)g_renewal_status_file, (size_t)strlen(g_renewal_status_file), KCM_CONFIG_ITEM, KCM_BACKUP_ITEM);
00422     SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed to delete renewal status");
00423 
00424     SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS();
00425 
00426     return KCM_STATUS_SUCCESS;
00427 }
00428 
00429 kcm_status_e  ce_store_new_certificate(const char *certificate_name, struct cert_chain_context_s *chain_data)
00430 {
00431 
00432     kcm_status_e  kcm_status = KCM_STATUS_SUCCESS;
00433     kcm_cert_chain_handle kcm_chain_handle;
00434     uint32_t cert_index = 0;
00435     uint8_t *certificate = NULL;
00436     size_t certificate_size = 0;
00437    // struct cert_chain_context_s current_chain_data;
00438     struct cert_context_s *current_certs;
00439 
00440     //Check parameters
00441     SA_PV_ERR_RECOVERABLE_RETURN_IF((certificate_name == NULL), kcm_status = KCM_STATUS_INVALID_PARAMETER, "Invalid certificate_name");
00442     SA_PV_ERR_RECOVERABLE_RETURN_IF((chain_data == NULL), kcm_status = KCM_STATUS_INVALID_PARAMETER, "Invalid chain_data");
00443     SA_PV_ERR_RECOVERABLE_RETURN_IF((chain_data->chain_length == 0), kcm_status = KCM_STATUS_INVALID_PARAMETER, "Invalid certificate chain length");
00444     SA_PV_ERR_RECOVERABLE_RETURN_IF((chain_data->certs == NULL), kcm_status = KCM_STATUS_INVALID_PARAMETER, "Invalid certificate data");
00445     SA_PV_ERR_RECOVERABLE_RETURN_IF((chain_data->certs->cert == NULL), kcm_status = KCM_STATUS_INVALID_PARAMETER, "Invalid first certificate pointer");
00446     SA_PV_ERR_RECOVERABLE_RETURN_IF((chain_data->certs->cert_length == 0), kcm_status = KCM_STATUS_INVALID_PARAMETER, "Invalid first certificate length");
00447     SA_PV_LOG_INFO_FUNC_ENTER("certificate_name =  %s", certificate_name);
00448 
00449 
00450     //Get first certificate
00451     current_certs = chain_data->certs;
00452     certificate = current_certs->cert;
00453     certificate_size = current_certs->cert_length;
00454 
00455     if (chain_data->chain_length == 1) {
00456         //Save single certificate
00457         kcm_status = storage_data_write((const uint8_t*)certificate_name,(size_t)strlen(certificate_name), KCM_CERTIFICATE_ITEM, false, KCM_ORIGINAL_ITEM,certificate, certificate_size );
00458         SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed to store new certificate");
00459 
00460         return kcm_status;
00461     } else {
00462          //Save chain 
00463         kcm_status = storage_cert_chain_create(&kcm_chain_handle, (const uint8_t*)certificate_name,(size_t) strlen(certificate_name), chain_data->chain_length, false, KCM_ORIGINAL_ITEM);
00464         SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed to create chain");
00465 
00466         for (cert_index = 0; cert_index < chain_data->chain_length ; cert_index++)
00467         {
00468             SA_PV_ERR_RECOVERABLE_GOTO_IF((certificate_size == 0 || certificate == NULL), kcm_status = KCM_STATUS_INVALID_PARAMETER, exit, "Invalid certificate data at index %" PRIu32 "", cert_index);
00469 
00470             kcm_status = storage_chain_add_next(kcm_chain_handle, certificate, certificate_size, KCM_ORIGINAL_ITEM);
00471             SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status = kcm_status, exit, "Failed to store certificate at index %" PRIu32 "", cert_index);
00472 
00473             //Get next certificate
00474            // chain_data->certs = chain_data->certs->next;
00475             current_certs = current_certs->next;
00476             if (current_certs != NULL) {
00477                 certificate = current_certs->cert;
00478                 certificate_size = current_certs->cert_length;
00479             }
00480         }
00481     }
00482 
00483 exit:
00484     kcm_status = storage_cert_chain_close(kcm_chain_handle, KCM_ORIGINAL_ITEM);
00485     SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status = kcm_status, exit, "Failed to close chain");
00486 
00487     return kcm_status;
00488 }