Mayank Gupta / Mbed OS pelion-example-frdm

Dependencies:   FXAS21002 FXOS8700Q

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers CertificateRenewalData.cpp Source File

CertificateRenewalData.cpp

00001 // ----------------------------------------------------------------------------
00002 // Copyright 2018 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 
00017 #include "ce_tlv.h"
00018 #include "CertificateEnrollmentClientCommon.h"
00019 #include "CertificateRenewalData.h"
00020 #include "key_config_manager.h"
00021 #include "cs_der_keys_and_csrs.h"
00022 #include "pv_log.h"
00023 
00024 
00025 #include <string.h>
00026 #include <stdio.h>
00027 
00028 namespace CertificateEnrollmentClient {
00029 
00030     // Base class constructor - Allocate raw data so that it remains persistent
00031     CertificateRenewalDataBase::CertificateRenewalDataBase(const uint8_t *raw_data, size_t raw_data_size)
00032     {
00033         _raw_data_size = raw_data_size;
00034         cert_name = NULL;
00035         csr = NULL;
00036         csr_size = 0;
00037         est_data = NULL;
00038         key_handle = 0;
00039         _raw_data = (uint8_t *)malloc(raw_data_size);        
00040         memcpy(_raw_data, raw_data, _raw_data_size);
00041     }
00042 
00043     // Free _raw_data, private_key, public_key (base destructor is called implicitly after derived destructor), 
00044     CertificateRenewalDataBase::~CertificateRenewalDataBase()
00045     {
00046         kcm_status_e  kcm_status;
00047         ce_status_e  ce_status;
00048 
00049         free(_raw_data);
00050         free(csr);
00051 
00052         // Release the key handle, this shouldn't fail...
00053         kcm_status = cs_ec_key_free(&key_handle);
00054         ce_status = ce_error_handler(kcm_status);
00055 
00056         if (ce_status != CE_STATUS_SUCCESS) {
00057             SA_PV_LOG_ERR("Failed releasing CSR's key handle (status %u)\n", kcm_status);
00058         }
00059     }
00060 
00061     CertificateRenewalDataFromServer::CertificateRenewalDataFromServer(const uint8_t *raw_data, size_t raw_data_size) :
00062         CertificateRenewalDataBase(raw_data, raw_data_size)
00063     {
00064     }
00065 
00066     CertificateRenewalDataFromServer::~CertificateRenewalDataFromServer()
00067     {
00068     }
00069 
00070     // Parse the CertificateRenewalDataFromServer::data as a CBOR and retrieve the cert name and size
00071     ce_status_e  CertificateRenewalDataFromServer::parse()
00072     {
00073         // NOTE: We should treat the TLV's VALUE according to the given type
00074         //       since there is only one type at the moment no parsing is needed.
00075 
00076         ce_tlv_status_e status;
00077         ce_tlv_element_s element;
00078         
00079         cert_name = NULL;
00080 
00081         if (ce_tlv_parser_init(_raw_data, _raw_data_size, &element) != CE_TLV_STATUS_SUCCESS) {
00082             return CE_STATUS_BAD_INPUT_FROM_SERVER;
00083         }
00084 
00085         while ((status = ce_tlv_parse_next(&element)) != CE_TLV_STATUS_END) {
00086             if (status != CE_TLV_STATUS_SUCCESS) {
00087                 // something got wrong while parsing
00088                 return CE_STATUS_BAD_INPUT_FROM_SERVER;
00089             }
00090 
00091             // element parsed successfully - check if type supported
00092 
00093             if ((element.type != CE_TLV_TYPE_CERT_NAME) && (is_required(&element))) {
00094                 return CE_STATUS_BAD_INPUT_FROM_SERVER;
00095             } else if ((element.type != CE_TLV_TYPE_CERT_NAME) && (!is_required(&element))) {
00096                 // unsupported type but optional - ignored
00097                 continue;
00098             }
00099 
00100             cert_name = element.val.text;
00101             SA_PV_LOG_INFO("\nParsed certificate to be updated is %s\n", (char *)element.val.text);
00102         }
00103 
00104         if (cert_name == NULL) {
00105             // parsing succeeded however we haven't got a concrete certificate name
00106             return CE_STATUS_BAD_INPUT_FROM_SERVER;
00107         }
00108 
00109         return CE_STATUS_SUCCESS;
00110     };
00111 
00112     // call the user callback and send message to the cloud
00113     void CertificateRenewalDataFromServer::finish(ce_status_e  status)
00114     {
00115         SA_PV_LOG_INFO("sending delayed response, status: %d\n", (int)status);
00116         g_cert_enroll_lwm2m_resource->set_value((int64_t)status);
00117         g_cert_enroll_lwm2m_resource->send_delayed_post_response();
00118 
00119         // Call the user callback after setting the resource so that the user may delete the MCC object from the CB.
00120         // If we had called the CB prior to setting the resource value, this would result in writing to unallocated memory.
00121         call_user_cert_renewal_cb(cert_name, status, CE_INITIATOR_SERVER);
00122     };
00123 
00124     CertificateRenewalDataFromDevice::CertificateRenewalDataFromDevice(const char *raw_data) :
00125         CertificateRenewalDataBase((uint8_t *)raw_data, (strlen(raw_data) + 1))
00126     {
00127     }
00128 
00129     CertificateRenewalDataFromDevice::~CertificateRenewalDataFromDevice()
00130     {
00131     }
00132 
00133     // Nothing to do other than set the cert_name field
00134     ce_status_e  CertificateRenewalDataFromDevice::parse()
00135     {
00136         cert_name = (const char *)_raw_data;
00137         return CE_STATUS_SUCCESS;
00138     }
00139 
00140     // Call the user callback but do not send anything to the server
00141     void CertificateRenewalDataFromDevice::finish(ce_status_e  status)
00142     {
00143         call_user_cert_renewal_cb(cert_name, status, CE_INITIATOR_DEVICE);
00144     }
00145 
00146 }