Committer:
leothedragon
Date:
Sun Apr 18 15:20:23 2021 +0000
Revision:
0:25fa8795676b
DS

Who changed what in which revision?

UserRevisionLine numberNew contents of line
leothedragon 0:25fa8795676b 1 // ----------------------------------------------------------------------------
leothedragon 0:25fa8795676b 2 // Copyright 2018 ARM Ltd.
leothedragon 0:25fa8795676b 3 //
leothedragon 0:25fa8795676b 4 // Licensed under the Apache License, Version 2.0 (the "License");
leothedragon 0:25fa8795676b 5 // you may not use this file except in compliance with the License.
leothedragon 0:25fa8795676b 6 // You may obtain a copy of the License at
leothedragon 0:25fa8795676b 7 //
leothedragon 0:25fa8795676b 8 // http://www.apache.org/licenses/LICENSE-2.0
leothedragon 0:25fa8795676b 9 //
leothedragon 0:25fa8795676b 10 // Unless required by applicable law or agreed to in writing, software
leothedragon 0:25fa8795676b 11 // distributed under the License is distributed on an "AS IS" BASIS,
leothedragon 0:25fa8795676b 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
leothedragon 0:25fa8795676b 13 // See the License for the specific language governing permissions and
leothedragon 0:25fa8795676b 14 // limitations under the License.
leothedragon 0:25fa8795676b 15 // ----------------------------------------------------------------------------
leothedragon 0:25fa8795676b 16
leothedragon 0:25fa8795676b 17
leothedragon 0:25fa8795676b 18 #include "CertificateEnrollmentClient.h"
leothedragon 0:25fa8795676b 19 #include "mbed-client/m2mresource.h"
leothedragon 0:25fa8795676b 20 #include "mbed-client/m2minterfacefactory.h"
leothedragon 0:25fa8795676b 21 #include "mbed-client/m2minterface.h"
leothedragon 0:25fa8795676b 22 #include "pal.h"
leothedragon 0:25fa8795676b 23 #include "eventOS_scheduler.h"
leothedragon 0:25fa8795676b 24 #include "eventOS_event.h"
leothedragon 0:25fa8795676b 25 #include "ce_defs.h"
leothedragon 0:25fa8795676b 26 #include "ce_tlv.h"
leothedragon 0:25fa8795676b 27 #include "certificate_enrollment.h"
leothedragon 0:25fa8795676b 28 #include <stdio.h>
leothedragon 0:25fa8795676b 29 #include <string.h>
leothedragon 0:25fa8795676b 30 #include "CertificateEnrollmentClient.h"
leothedragon 0:25fa8795676b 31 #include "CertificateEnrollmentClientCommon.h"
leothedragon 0:25fa8795676b 32 #include "CertificateRenewalData.h"
leothedragon 0:25fa8795676b 33 #include "pv_error_handling.h"
leothedragon 0:25fa8795676b 34 #include "pv_macros.h"
leothedragon 0:25fa8795676b 35
leothedragon 0:25fa8795676b 36 #define RESOURCE_ID_CERTIFICATE_NAME "27002"
leothedragon 0:25fa8795676b 37 #define OBJECT_LWM2M_CERTIFICATE "35011"
leothedragon 0:25fa8795676b 38
leothedragon 0:25fa8795676b 39 #define NUMBER_OF_CONCURRENT_RENEWALS 1
leothedragon 0:25fa8795676b 40
leothedragon 0:25fa8795676b 41
leothedragon 0:25fa8795676b 42 /************************************************************************/
leothedragon 0:25fa8795676b 43 /* Different calls to update */
leothedragon 0:25fa8795676b 44 /************************************************************************/
leothedragon 0:25fa8795676b 45
leothedragon 0:25fa8795676b 46 extern const char g_lwm2m_name[];
leothedragon 0:25fa8795676b 47
leothedragon 0:25fa8795676b 48 namespace CertificateEnrollmentClient {
leothedragon 0:25fa8795676b 49
leothedragon 0:25fa8795676b 50 // Event type that is part of the arm_event_s structure.
leothedragon 0:25fa8795676b 51 enum event_type_e {
leothedragon 0:25fa8795676b 52 EVENT_TYPE_INIT, // Some initializer - nothing done currently, initialization called by mbed cloud client
leothedragon 0:25fa8795676b 53 EVENT_TYPE_RENEWAL_REQUEST, // Certificate renewal request. We can tell if it is initiated by the server or the device with the derived type of CertificateRenewalDataBase of the certificate descriptor / global variable
leothedragon 0:25fa8795676b 54 EVENT_TYPE_EST_RESPONDED, // Certificate arrived from EST service, or EST failure
leothedragon 0:25fa8795676b 55 EVENT_TYPE_MAX = 0xff // Must fit in a uint8_t (field in the arm_event_s struct)
leothedragon 0:25fa8795676b 56 };
leothedragon 0:25fa8795676b 57
leothedragon 0:25fa8795676b 58 // Pointer to the EST client object for dealing with the EST service.
leothedragon 0:25fa8795676b 59 extern const CERT_ENROLLMENT_EST_CLIENT *g_est_client;
leothedragon 0:25fa8795676b 60
leothedragon 0:25fa8795676b 61 // Data for certificate that is currently being renewed. Will change to list if we need to support multiple renewals
leothedragon 0:25fa8795676b 62 static CertificateRenewalDataBase *current_cert = NULL;
leothedragon 0:25fa8795676b 63
leothedragon 0:25fa8795676b 64 // ID of the handler we register to the MbedCloudClient event loop
leothedragon 0:25fa8795676b 65 static int8_t handler_id = -1;
leothedragon 0:25fa8795676b 66
leothedragon 0:25fa8795676b 67 // Flag that indicates whether the module is initialized
leothedragon 0:25fa8795676b 68 static bool is_initialized = false;
leothedragon 0:25fa8795676b 69
leothedragon 0:25fa8795676b 70 // Semaphore for enforcing that only NUMBER_OF_CONCURRENT_RENEWALS (currently 1) request at a time may update current_cert. Hold lock until process finished.
leothedragon 0:25fa8795676b 71 // Important: When pal_osSemaphoreWait called from within event loop - do not block, must set timeout to 0, and fail if failed to acquire lock
leothedragon 0:25fa8795676b 72 // Future: For supporting renewals of NUMBER_OF_CONCURRENT_RENEWALS certificates simultaneously - change to semaphore that counts to NUMBER_OF_CONCURRENT_RENEWALS
leothedragon 0:25fa8795676b 73 // and maintain a list of certificates of size NUMBER_OF_CONCURRENT_RENEWALS inside the event loop.
leothedragon 0:25fa8795676b 74 static palSemaphoreID_t g_renewal_sem = 0;
leothedragon 0:25fa8795676b 75
leothedragon 0:25fa8795676b 76
leothedragon 0:25fa8795676b 77 /**
leothedragon 0:25fa8795676b 78 * \brief Finish the renewal process.
leothedragon 0:25fa8795676b 79 * Zero current_cert pointer, then release the semaphore. Note that when the semaphore is released - new device renewals may be made.
leothedragon 0:25fa8795676b 80 * Then call renewal_data->finish() and delete renewal_data.
leothedragon 0:25fa8795676b 81 *
leothedragon 0:25fa8795676b 82 * \param renewal_data the data of the certificate to be renewed.
leothedragon 0:25fa8795676b 83 * It is important that this is passed to the function because after releasing the semaphore - the global pointer may be replaced.
leothedragon 0:25fa8795676b 84 * \param exit_status the status of the renewal process
leothedragon 0:25fa8795676b 85 */
leothedragon 0:25fa8795676b 86 static void certificate_renewal_finish(CertificateRenewalDataBase *renewal_data, ce_status_e exit_status);
leothedragon 0:25fa8795676b 87
leothedragon 0:25fa8795676b 88 /**
leothedragon 0:25fa8795676b 89 * \brief The function that handles all the CertificateEnrollmentClient events
leothedragon 0:25fa8795676b 90 * Create an arm_event_s object and call eventOS_event_send()
leothedragon 0:25fa8795676b 91 * The event will have an application level priority, and will be executed when in the head of the event queue.
leothedragon 0:25fa8795676b 92 * In the future: an extra arg should be passed - some descriptor for the specific CertificateRenewalDataBase object.
leothedragon 0:25fa8795676b 93 *
leothedragon 0:25fa8795676b 94 * \param event_type An event identifier
leothedragon 0:25fa8795676b 95 */
leothedragon 0:25fa8795676b 96 static void event_handler(arm_event_s* event);
leothedragon 0:25fa8795676b 97
leothedragon 0:25fa8795676b 98 /**
leothedragon 0:25fa8795676b 99 * \brief Send a new event to the event loop queue.
leothedragon 0:25fa8795676b 100 * Create an arm_event_s object and call eventOS_event_send()
leothedragon 0:25fa8795676b 101 * The event will have an application level priority
leothedragon 0:25fa8795676b 102 *
leothedragon 0:25fa8795676b 103 * \param renewal_data A pointer to an object derived from CertificateRenewalDataBase
leothedragon 0:25fa8795676b 104 * \param event_type An event identifier
leothedragon 0:25fa8795676b 105 */
leothedragon 0:25fa8795676b 106 static ce_status_e schedule_event(event_type_e event_type);
leothedragon 0:25fa8795676b 107
leothedragon 0:25fa8795676b 108 /**
leothedragon 0:25fa8795676b 109 * \brief Callback that will be executed when an EST service response is available
leothedragon 0:25fa8795676b 110 * Event Context is probably network so this function will check if response is success, if so, allocate the data if needed in renewal_data->est_data. schedule a new event with type EVENT_TYPE_EST_RESPONDED.
leothedragon 0:25fa8795676b 111 *
leothedragon 0:25fa8795676b 112 * \param result Whether the EST client successfully received a certificate from the EST service
leothedragon 0:25fa8795676b 113 * \param cert_chain structure containing the certificate/chain received from the EST service
leothedragon 0:25fa8795676b 114 * \param Context passed when requesting a certificate via the EST client. Currently unused. In the future will be used to identify the relevant CertificateRenewalDataBase object.
leothedragon 0:25fa8795676b 115 */
leothedragon 0:25fa8795676b 116 static void est_cb(est_enrollment_result_e result,
leothedragon 0:25fa8795676b 117 cert_chain_context_s *cert_chain,
leothedragon 0:25fa8795676b 118 void *context);
leothedragon 0:25fa8795676b 119
leothedragon 0:25fa8795676b 120 /**
leothedragon 0:25fa8795676b 121 * \brief The function that handles the EST response.
leothedragon 0:25fa8795676b 122 *
leothedragon 0:25fa8795676b 123 * Called by event_handler(). renewal_data->est_data already exists and is valid.
leothedragon 0:25fa8795676b 124 * Will perform a safe replacement of the certificate with the new certificate received from EST
leothedragon 0:25fa8795676b 125 * Then it will free the EST chain and finish the renewal operation.
leothedragon 0:25fa8795676b 126 * \param renewal_data A pointer to an object derived from CertificateRenewalDataBase
leothedragon 0:25fa8795676b 127 */
leothedragon 0:25fa8795676b 128 static void est_response_process(CertificateRenewalDataBase *renewal_data);
leothedragon 0:25fa8795676b 129
leothedragon 0:25fa8795676b 130 /**
leothedragon 0:25fa8795676b 131 * \brief Create g_cert_enroll_lwm2m_obj, from the object create an object resource, and create the resources. Then push the object to the MCC object list
leothedragon 0:25fa8795676b 132 *
leothedragon 0:25fa8795676b 133 * Note that the pointers to the objects created by this function is owned by the CertificateEnrollmentClient Module and must be released in by CertificateEnrollmentClient::finalize()
leothedragon 0:25fa8795676b 134 * \param list A reference to the MbedCloudClient object list. MbedCloudClient will later set the resource
leothedragon 0:25fa8795676b 135 */
leothedragon 0:25fa8795676b 136 static ce_status_e init_objects(M2MBaseList& list);
leothedragon 0:25fa8795676b 137
leothedragon 0:25fa8795676b 138 /**
leothedragon 0:25fa8795676b 139 * \brief Release the objects created by init_objects()
leothedragon 0:25fa8795676b 140 *
leothedragon 0:25fa8795676b 141 */
leothedragon 0:25fa8795676b 142 static void release_objects();
leothedragon 0:25fa8795676b 143
leothedragon 0:25fa8795676b 144 // Callback is called when we get a POST message to g_cert_enroll_lwm2m_resource (runs in high priority context!)
leothedragon 0:25fa8795676b 145 /**
leothedragon 0:25fa8795676b 146 * \brief Callback is called when we get a POST message to g_cert_enroll_lwm2m_resource
leothedragon 0:25fa8795676b 147 * Runs in network context of the event loop.
leothedragon 0:25fa8795676b 148 * This function extracts the input data, creates a CertificateEnrollmentClient::CertificateRenewalDataFromServer object sets the global variable
leothedragon 0:25fa8795676b 149 *
leothedragon 0:25fa8795676b 150 * \param arg a M2MResource::M2MExecuteParameter argument.
leothedragon 0:25fa8795676b 151 */
leothedragon 0:25fa8795676b 152 static void certificate_renewal_post(void *arg);
leothedragon 0:25fa8795676b 153
leothedragon 0:25fa8795676b 154 /**
leothedragon 0:25fa8795676b 155 * \brief Start the renewal process.
leothedragon 0:25fa8795676b 156 * Parse the certificate name, generate keys and CSR. Then call the EST client so the new certificate may be retrieved
leothedragon 0:25fa8795676b 157 *
leothedragon 0:25fa8795676b 158 * \param renewal_data the data of the certificate to be renewed
leothedragon 0:25fa8795676b 159 */
leothedragon 0:25fa8795676b 160 static void certificate_renewal_start(CertificateRenewalDataBase *renewal_data);
leothedragon 0:25fa8795676b 161
leothedragon 0:25fa8795676b 162 /**
leothedragon 0:25fa8795676b 163 * \brief Call the user callback and send a response to the server, when a CertificateRenewalDataFromServer object does not exist.
leothedragon 0:25fa8795676b 164 * Use only for server initiated renewal, since this sends a response to the server.
leothedragon 0:25fa8795676b 165 *
leothedragon 0:25fa8795676b 166 * \param tlv the raw data from the server - should be in the form of TLV
leothedragon 0:25fa8795676b 167 * \param tlv_size size of the TLV buffer
leothedragon 0:25fa8795676b 168 * \param ret_status The return status to return to the user callback and the server
leothedragon 0:25fa8795676b 169 */
leothedragon 0:25fa8795676b 170 static void call_user_cb_send_response(const uint8_t *tlv, uint16_t tlv_size, ce_status_e ret_status);
leothedragon 0:25fa8795676b 171
leothedragon 0:25fa8795676b 172 #ifdef CERT_RENEWAL_TEST
leothedragon 0:25fa8795676b 173 void testonly_certificate_renewal_post(void *arg);
leothedragon 0:25fa8795676b 174 #endif // CERT_RENEWAL_TEST
leothedragon 0:25fa8795676b 175
leothedragon 0:25fa8795676b 176 }
leothedragon 0:25fa8795676b 177
leothedragon 0:25fa8795676b 178 // FIXME: print error
leothedragon 0:25fa8795676b 179 void CertificateEnrollmentClient::call_user_cb_send_response(const uint8_t *tlv, uint16_t tlv_size, ce_status_e ret_status)
leothedragon 0:25fa8795676b 180 {
leothedragon 0:25fa8795676b 181 CertificateEnrollmentClient::CertificateRenewalDataFromServer temp_obj(tlv, tlv_size);
leothedragon 0:25fa8795676b 182 (void)temp_obj.parse();
leothedragon 0:25fa8795676b 183
leothedragon 0:25fa8795676b 184 // Call user callback with appropriate error
leothedragon 0:25fa8795676b 185 // In case of parsing error (malformed TLV), the provided ret_status will be returned and not
leothedragon 0:25fa8795676b 186 call_user_cert_renewal_cb(temp_obj.cert_name, ret_status, CE_INITIATOR_SERVER);
leothedragon 0:25fa8795676b 187
leothedragon 0:25fa8795676b 188 // Send response to the server
leothedragon 0:25fa8795676b 189 SA_PV_LOG_INFO("sending delayed response\n");
leothedragon 0:25fa8795676b 190 g_cert_enroll_lwm2m_resource->set_value(ret_status);
leothedragon 0:25fa8795676b 191 g_cert_enroll_lwm2m_resource->send_delayed_post_response();
leothedragon 0:25fa8795676b 192 }
leothedragon 0:25fa8795676b 193
leothedragon 0:25fa8795676b 194 void CertificateEnrollmentClient::certificate_renewal_post(void *arg)
leothedragon 0:25fa8795676b 195 {
leothedragon 0:25fa8795676b 196 palStatus_t pal_status;
leothedragon 0:25fa8795676b 197 ce_status_e status;
leothedragon 0:25fa8795676b 198 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS();
leothedragon 0:25fa8795676b 199
leothedragon 0:25fa8795676b 200 M2MResource::M2MExecuteParameter *args = (M2MResource::M2MExecuteParameter *)arg;
leothedragon 0:25fa8795676b 201 const uint8_t *data = args->get_argument_value();
leothedragon 0:25fa8795676b 202 const uint16_t data_size = args->get_argument_value_length();
leothedragon 0:25fa8795676b 203
leothedragon 0:25fa8795676b 204 // If CEC module is not initialized - do not even take semaphore - exit with proper response
leothedragon 0:25fa8795676b 205 SA_PV_ERR_RECOVERABLE_RETURN_IF((!is_initialized), call_user_cb_send_response(data, data_size, CE_STATUS_NOT_INITIALIZED), "Certificate Renewal module not initialized");
leothedragon 0:25fa8795676b 206
leothedragon 0:25fa8795676b 207 pal_status = pal_osSemaphoreWait(g_renewal_sem, 0, NULL);
leothedragon 0:25fa8795676b 208
leothedragon 0:25fa8795676b 209 if (pal_status == PAL_SUCCESS) {
leothedragon 0:25fa8795676b 210 CertificateEnrollmentClient::current_cert = new CertificateEnrollmentClient::CertificateRenewalDataFromServer(data, data_size);
leothedragon 0:25fa8795676b 211 if (!CertificateEnrollmentClient::current_cert) {
leothedragon 0:25fa8795676b 212 status = CE_STATUS_OUT_OF_MEMORY;
leothedragon 0:25fa8795676b 213 pal_status = pal_osSemaphoreRelease(g_renewal_sem);
leothedragon 0:25fa8795676b 214 if (PAL_SUCCESS != pal_status) { // Should never happen
leothedragon 0:25fa8795676b 215 status = CE_STATUS_ERROR;
leothedragon 0:25fa8795676b 216 }
leothedragon 0:25fa8795676b 217
leothedragon 0:25fa8795676b 218 call_user_cb_send_response(data, data_size, status);
leothedragon 0:25fa8795676b 219 return;
leothedragon 0:25fa8795676b 220 }
leothedragon 0:25fa8795676b 221
leothedragon 0:25fa8795676b 222 // Enqueue the event
leothedragon 0:25fa8795676b 223 status = schedule_event(CertificateEnrollmentClient::EVENT_TYPE_RENEWAL_REQUEST);
leothedragon 0:25fa8795676b 224 SA_PV_ERR_RECOVERABLE_RETURN_IF((status != CE_STATUS_SUCCESS), certificate_renewal_finish(CertificateEnrollmentClient::current_cert, status), "Error scheduling event");
leothedragon 0:25fa8795676b 225
leothedragon 0:25fa8795676b 226 } else {
leothedragon 0:25fa8795676b 227 SA_PV_LOG_ERR("Failed to take semaphore- device busy\n");
leothedragon 0:25fa8795676b 228
leothedragon 0:25fa8795676b 229 if (pal_status == PAL_ERR_RTOS_TIMEOUT) {
leothedragon 0:25fa8795676b 230 status = CE_STATUS_DEVICE_BUSY;
leothedragon 0:25fa8795676b 231 } else {
leothedragon 0:25fa8795676b 232 status = CE_STATUS_ERROR;
leothedragon 0:25fa8795676b 233 }
leothedragon 0:25fa8795676b 234
leothedragon 0:25fa8795676b 235 call_user_cb_send_response(data, data_size, status);
leothedragon 0:25fa8795676b 236 return;
leothedragon 0:25fa8795676b 237 }
leothedragon 0:25fa8795676b 238
leothedragon 0:25fa8795676b 239 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS();
leothedragon 0:25fa8795676b 240 }
leothedragon 0:25fa8795676b 241
leothedragon 0:25fa8795676b 242 ce_status_e CertificateEnrollmentClient::certificate_renew(const char *cert_name)
leothedragon 0:25fa8795676b 243 {
leothedragon 0:25fa8795676b 244 palStatus_t pal_status = PAL_SUCCESS;
leothedragon 0:25fa8795676b 245 ce_status_e status = CE_STATUS_SUCCESS;
leothedragon 0:25fa8795676b 246
leothedragon 0:25fa8795676b 247 SA_PV_ERR_RECOVERABLE_RETURN_IF((!cert_name), CE_STATUS_INVALID_PARAMETER, "Provided NULL certificate name");
leothedragon 0:25fa8795676b 248 SA_PV_ERR_RECOVERABLE_RETURN_IF((!is_initialized), CE_STATUS_NOT_INITIALIZED, "Certificate Renewal module not initialized");
leothedragon 0:25fa8795676b 249
leothedragon 0:25fa8795676b 250 SA_PV_LOG_INFO_FUNC_ENTER("cert_name = %s\n", cert_name);
leothedragon 0:25fa8795676b 251
leothedragon 0:25fa8795676b 252 pal_status = pal_osSemaphoreWait(g_renewal_sem, 0, NULL);
leothedragon 0:25fa8795676b 253
leothedragon 0:25fa8795676b 254 if (pal_status == PAL_SUCCESS) {
leothedragon 0:25fa8795676b 255 CertificateEnrollmentClient::current_cert = new CertificateEnrollmentClient::CertificateRenewalDataFromDevice(cert_name);
leothedragon 0:25fa8795676b 256 SA_PV_ERR_RECOVERABLE_GOTO_IF((!CertificateEnrollmentClient::current_cert), status = CE_STATUS_OUT_OF_MEMORY, ReleseSemReturn, "Allocation error");
leothedragon 0:25fa8795676b 257
leothedragon 0:25fa8795676b 258 // Enqueue the event
leothedragon 0:25fa8795676b 259 status = schedule_event(CertificateEnrollmentClient::EVENT_TYPE_RENEWAL_REQUEST);
leothedragon 0:25fa8795676b 260 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != CE_STATUS_SUCCESS), status = status, ReleseSemReturn, "Error scheduling event");
leothedragon 0:25fa8795676b 261
leothedragon 0:25fa8795676b 262 // If some error synchronous error has occurred before scheduling the event - release the semaphore we had just taken,
leothedragon 0:25fa8795676b 263 // and then return the error without calling the user callback
leothedragon 0:25fa8795676b 264 ReleseSemReturn:
leothedragon 0:25fa8795676b 265 if (status != CE_STATUS_SUCCESS) {
leothedragon 0:25fa8795676b 266 pal_status = pal_osSemaphoreRelease(g_renewal_sem);
leothedragon 0:25fa8795676b 267 if (PAL_SUCCESS != pal_status) { // Should never happen
leothedragon 0:25fa8795676b 268 status = CE_STATUS_ERROR;
leothedragon 0:25fa8795676b 269 }
leothedragon 0:25fa8795676b 270 }
leothedragon 0:25fa8795676b 271
leothedragon 0:25fa8795676b 272 } else {
leothedragon 0:25fa8795676b 273 // return with appropriate error
leothedragon 0:25fa8795676b 274 if (pal_status == PAL_ERR_RTOS_TIMEOUT) {
leothedragon 0:25fa8795676b 275 status = CE_STATUS_DEVICE_BUSY;
leothedragon 0:25fa8795676b 276 } else {
leothedragon 0:25fa8795676b 277 status = CE_STATUS_ERROR;
leothedragon 0:25fa8795676b 278 }
leothedragon 0:25fa8795676b 279
leothedragon 0:25fa8795676b 280 }
leothedragon 0:25fa8795676b 281
leothedragon 0:25fa8795676b 282 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS();
leothedragon 0:25fa8795676b 283 return status;
leothedragon 0:25fa8795676b 284 }
leothedragon 0:25fa8795676b 285
leothedragon 0:25fa8795676b 286
leothedragon 0:25fa8795676b 287 void CertificateEnrollmentClient::on_certificate_renewal(cert_renewal_cb_f user_cb)
leothedragon 0:25fa8795676b 288 {
leothedragon 0:25fa8795676b 289 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS();
leothedragon 0:25fa8795676b 290 CertificateEnrollmentClient::set_user_cert_renewal_cb(user_cb);
leothedragon 0:25fa8795676b 291 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS();
leothedragon 0:25fa8795676b 292 }
leothedragon 0:25fa8795676b 293
leothedragon 0:25fa8795676b 294
leothedragon 0:25fa8795676b 295 ce_status_e CertificateEnrollmentClient::init_objects(M2MBaseList& list)
leothedragon 0:25fa8795676b 296 {
leothedragon 0:25fa8795676b 297 M2MObjectInstance *cert_enroll_lwm2m_obj_instance;
leothedragon 0:25fa8795676b 298
leothedragon 0:25fa8795676b 299 ce_status_e ce_status = CE_STATUS_SUCCESS;
leothedragon 0:25fa8795676b 300 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS();
leothedragon 0:25fa8795676b 301
leothedragon 0:25fa8795676b 302 // Create the certificate enrollment resource
leothedragon 0:25fa8795676b 303 g_cert_enroll_lwm2m_obj = M2MInterfaceFactory::create_object(OBJECT_LWM2M_CERTIFICATE);
leothedragon 0:25fa8795676b 304 SA_PV_ERR_RECOVERABLE_RETURN_IF((!g_cert_enroll_lwm2m_obj), CE_STATUS_ERROR, "Error creating LWM2M object");
leothedragon 0:25fa8795676b 305
leothedragon 0:25fa8795676b 306 // Create the instance
leothedragon 0:25fa8795676b 307 cert_enroll_lwm2m_obj_instance = g_cert_enroll_lwm2m_obj->create_object_instance();
leothedragon 0:25fa8795676b 308 SA_PV_ERR_RECOVERABLE_GOTO_IF((!cert_enroll_lwm2m_obj_instance), ce_status = CE_STATUS_ERROR, Cleanup, "Error creating LWM2M object instance");
leothedragon 0:25fa8795676b 309
leothedragon 0:25fa8795676b 310 // Create the resource
leothedragon 0:25fa8795676b 311 g_cert_enroll_lwm2m_resource = cert_enroll_lwm2m_obj_instance->create_dynamic_resource(RESOURCE_ID_CERTIFICATE_NAME, "Enroll", M2MResourceInstance::INTEGER, false);
leothedragon 0:25fa8795676b 312 SA_PV_ERR_RECOVERABLE_GOTO_IF((!g_cert_enroll_lwm2m_resource), ce_status = CE_STATUS_ERROR, Cleanup, "Error creating LWM2M resource");
leothedragon 0:25fa8795676b 313
leothedragon 0:25fa8795676b 314 // Allow POST operations
leothedragon 0:25fa8795676b 315 g_cert_enroll_lwm2m_resource->set_operation(M2MBase::POST_ALLOWED);
leothedragon 0:25fa8795676b 316
leothedragon 0:25fa8795676b 317 // Set the resource callback
leothedragon 0:25fa8795676b 318 SA_PV_ERR_RECOVERABLE_GOTO_IF((!g_cert_enroll_lwm2m_resource->set_execute_function(CertificateEnrollmentClient::certificate_renewal_post)),
leothedragon 0:25fa8795676b 319 ce_status = CE_STATUS_ERROR, Cleanup, "Error resource callback");
leothedragon 0:25fa8795676b 320
leothedragon 0:25fa8795676b 321 // Enable sending of delayed responses
leothedragon 0:25fa8795676b 322 g_cert_enroll_lwm2m_resource->set_delayed_response(true);
leothedragon 0:25fa8795676b 323
leothedragon 0:25fa8795676b 324 // Push the object to the list
leothedragon 0:25fa8795676b 325 list.push_back(g_cert_enroll_lwm2m_obj);
leothedragon 0:25fa8795676b 326
leothedragon 0:25fa8795676b 327 Cleanup:
leothedragon 0:25fa8795676b 328 if (ce_status != CE_STATUS_SUCCESS) {
leothedragon 0:25fa8795676b 329 // Destroying the object will destroy all instances and resources associated with it
leothedragon 0:25fa8795676b 330 delete g_cert_enroll_lwm2m_obj;
leothedragon 0:25fa8795676b 331 g_cert_enroll_lwm2m_resource = NULL;
leothedragon 0:25fa8795676b 332 }
leothedragon 0:25fa8795676b 333
leothedragon 0:25fa8795676b 334 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS();
leothedragon 0:25fa8795676b 335 return ce_status;
leothedragon 0:25fa8795676b 336 }
leothedragon 0:25fa8795676b 337
leothedragon 0:25fa8795676b 338 void CertificateEnrollmentClient::release_objects()
leothedragon 0:25fa8795676b 339 {
leothedragon 0:25fa8795676b 340 delete g_cert_enroll_lwm2m_obj;
leothedragon 0:25fa8795676b 341 g_cert_enroll_lwm2m_obj = NULL;
leothedragon 0:25fa8795676b 342 }
leothedragon 0:25fa8795676b 343
leothedragon 0:25fa8795676b 344
leothedragon 0:25fa8795676b 345 ce_status_e CertificateEnrollmentClient::init(M2MBaseList& list, const EstClient *est_client)
leothedragon 0:25fa8795676b 346 {
leothedragon 0:25fa8795676b 347 ce_status_e ce_status = CE_STATUS_SUCCESS;
leothedragon 0:25fa8795676b 348 palStatus_t pal_status = PAL_SUCCESS;
leothedragon 0:25fa8795676b 349
leothedragon 0:25fa8795676b 350 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS();
leothedragon 0:25fa8795676b 351
leothedragon 0:25fa8795676b 352 if (!is_initialized) {
leothedragon 0:25fa8795676b 353
leothedragon 0:25fa8795676b 354 // Init the LWM2M object and resource and push the object
leothedragon 0:25fa8795676b 355 ce_status = init_objects(list);
leothedragon 0:25fa8795676b 356 SA_PV_ERR_RECOVERABLE_RETURN_IF((ce_status != CE_STATUS_SUCCESS), ce_status, "Error initializing LWM2M object and resource");
leothedragon 0:25fa8795676b 357
leothedragon 0:25fa8795676b 358 // Put the handler creation in a critical code block for the case that this function is called after the start of the event loop
leothedragon 0:25fa8795676b 359 eventOS_scheduler_mutex_wait();
leothedragon 0:25fa8795676b 360 if (handler_id == -1) { // Register the handler only if it hadn't been registered before
leothedragon 0:25fa8795676b 361 handler_id = eventOS_event_handler_create(CertificateEnrollmentClient::event_handler, EVENT_TYPE_INIT);
leothedragon 0:25fa8795676b 362 SA_PV_ERR_RECOVERABLE_RETURN_IF((handler_id == -1), ce_status, "Error creating event handler");
leothedragon 0:25fa8795676b 363 }
leothedragon 0:25fa8795676b 364 eventOS_scheduler_mutex_release();
leothedragon 0:25fa8795676b 365
leothedragon 0:25fa8795676b 366 // Initialize the CE module
leothedragon 0:25fa8795676b 367 ce_status = ce_init();
leothedragon 0:25fa8795676b 368 SA_PV_ERR_RECOVERABLE_RETURN_IF((ce_status != CE_STATUS_SUCCESS), ce_status, "Error initializing CE module");
leothedragon 0:25fa8795676b 369
leothedragon 0:25fa8795676b 370 // Create the certificate renewal mutex
leothedragon 0:25fa8795676b 371 pal_status = pal_osSemaphoreCreate(NUMBER_OF_CONCURRENT_RENEWALS, &g_renewal_sem);
leothedragon 0:25fa8795676b 372 SA_PV_ERR_RECOVERABLE_RETURN_IF((pal_status != PAL_SUCCESS), CE_STATUS_ERROR, "Error creating semaphore");
leothedragon 0:25fa8795676b 373
leothedragon 0:25fa8795676b 374 #ifdef CERT_ENROLLMENT_EST_MOCK
leothedragon 0:25fa8795676b 375 PV_UNUSED_PARAM(est_client);
leothedragon 0:25fa8795676b 376 g_est_client = new EstClientMock();
leothedragon 0:25fa8795676b 377 SA_PV_ERR_RECOVERABLE_RETURN_IF((!g_est_client), CE_STATUS_ERROR, "Error creating mock EST");
leothedragon 0:25fa8795676b 378 #else
leothedragon 0:25fa8795676b 379 g_est_client = est_client;
leothedragon 0:25fa8795676b 380 #endif
leothedragon 0:25fa8795676b 381
leothedragon 0:25fa8795676b 382 is_initialized = true;
leothedragon 0:25fa8795676b 383 }
leothedragon 0:25fa8795676b 384
leothedragon 0:25fa8795676b 385 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS();
leothedragon 0:25fa8795676b 386 return CE_STATUS_SUCCESS;
leothedragon 0:25fa8795676b 387 }
leothedragon 0:25fa8795676b 388
leothedragon 0:25fa8795676b 389 void CertificateEnrollmentClient::finalize()
leothedragon 0:25fa8795676b 390 {
leothedragon 0:25fa8795676b 391 palStatus_t pal_status;
leothedragon 0:25fa8795676b 392 // If module not initialized - do nothing
leothedragon 0:25fa8795676b 393 if (is_initialized) {
leothedragon 0:25fa8795676b 394 pal_status = pal_osSemaphoreDelete(&g_renewal_sem);
leothedragon 0:25fa8795676b 395 if (pal_status != PAL_SUCCESS) {
leothedragon 0:25fa8795676b 396 SA_PV_LOG_ERR("Error deleting semaphore");
leothedragon 0:25fa8795676b 397 }
leothedragon 0:25fa8795676b 398
leothedragon 0:25fa8795676b 399 #ifdef CERT_ENROLLMENT_EST_MOCK
leothedragon 0:25fa8795676b 400 delete g_est_client;
leothedragon 0:25fa8795676b 401 #endif
leothedragon 0:25fa8795676b 402 is_initialized = false;
leothedragon 0:25fa8795676b 403
leothedragon 0:25fa8795676b 404 // LWM2M objects, instances, and resources are deleted when MbedCloudClient is unregistered and ServiceClient::state_unregister() is called
leothedragon 0:25fa8795676b 405 // Currently nothing to finalize for CE core module except for KCM. However we do not wish to finalize it it may be used by other resources
leothedragon 0:25fa8795676b 406
leothedragon 0:25fa8795676b 407 // Release our resources
leothedragon 0:25fa8795676b 408 release_objects();
leothedragon 0:25fa8795676b 409 }
leothedragon 0:25fa8795676b 410 }
leothedragon 0:25fa8795676b 411
leothedragon 0:25fa8795676b 412 void CertificateEnrollmentClient::event_handler(arm_event_s* event)
leothedragon 0:25fa8795676b 413 {
leothedragon 0:25fa8795676b 414 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS();
leothedragon 0:25fa8795676b 415
leothedragon 0:25fa8795676b 416 switch (event->event_type) {
leothedragon 0:25fa8795676b 417 case EVENT_TYPE_INIT:
leothedragon 0:25fa8795676b 418 // Nothing to do - ce module already initialized
leothedragon 0:25fa8795676b 419 break;
leothedragon 0:25fa8795676b 420 case EVENT_TYPE_RENEWAL_REQUEST:
leothedragon 0:25fa8795676b 421 certificate_renewal_start(current_cert);
leothedragon 0:25fa8795676b 422 break;
leothedragon 0:25fa8795676b 423 case EVENT_TYPE_EST_RESPONDED:
leothedragon 0:25fa8795676b 424 est_response_process(current_cert);
leothedragon 0:25fa8795676b 425 break;
leothedragon 0:25fa8795676b 426 default:
leothedragon 0:25fa8795676b 427 // Should never happen
leothedragon 0:25fa8795676b 428 SA_PV_LOG_ERR("Unsuupported event\n");
leothedragon 0:25fa8795676b 429 }
leothedragon 0:25fa8795676b 430
leothedragon 0:25fa8795676b 431 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS();
leothedragon 0:25fa8795676b 432 }
leothedragon 0:25fa8795676b 433
leothedragon 0:25fa8795676b 434 // This is the entry point of the renewal request, inside the event loop
leothedragon 0:25fa8795676b 435 void CertificateEnrollmentClient::certificate_renewal_start(CertificateRenewalDataBase *renewal_data)
leothedragon 0:25fa8795676b 436 {
leothedragon 0:25fa8795676b 437 ce_status_e ce_status;
leothedragon 0:25fa8795676b 438 est_status_e est_status;
leothedragon 0:25fa8795676b 439 const char *cert_name;
leothedragon 0:25fa8795676b 440 size_t cert_name_size;
leothedragon 0:25fa8795676b 441 kcm_status_e kcm_status;
leothedragon 0:25fa8795676b 442 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS();
leothedragon 0:25fa8795676b 443
leothedragon 0:25fa8795676b 444 // Parse the certificate name
leothedragon 0:25fa8795676b 445 ce_status = renewal_data->parse();
leothedragon 0:25fa8795676b 446 SA_PV_ERR_RECOVERABLE_RETURN_IF((ce_status != CE_STATUS_SUCCESS), certificate_renewal_finish(renewal_data, ce_status), "Parse error");
leothedragon 0:25fa8795676b 447
leothedragon 0:25fa8795676b 448 // Create CSR's key handle
leothedragon 0:25fa8795676b 449 kcm_status = cs_ec_key_new(&renewal_data->key_handle);
leothedragon 0:25fa8795676b 450
leothedragon 0:25fa8795676b 451 // translate error to some CE native error
leothedragon 0:25fa8795676b 452 ce_status = ce_error_handler(kcm_status);
leothedragon 0:25fa8795676b 453 SA_PV_ERR_RECOVERABLE_RETURN_IF((ce_status != CE_STATUS_SUCCESS), certificate_renewal_finish(renewal_data, ce_status), "Failed creating new key handle");
leothedragon 0:25fa8795676b 454
leothedragon 0:25fa8795676b 455 // key handle is initialized in the base constructor
leothedragon 0:25fa8795676b 456 ce_status = ce_generate_keys_and_create_csr_from_certificate(renewal_data->cert_name, renewal_data->key_handle, &renewal_data->csr, &renewal_data->csr_size);
leothedragon 0:25fa8795676b 457 SA_PV_ERR_RECOVERABLE_RETURN_IF((ce_status != CE_STATUS_SUCCESS), certificate_renewal_finish(renewal_data, ce_status), "Keys/CSR generation error");
leothedragon 0:25fa8795676b 458
leothedragon 0:25fa8795676b 459 // Call the EST client
leothedragon 0:25fa8795676b 460
leothedragon 0:25fa8795676b 461 // If lwm2m device certificate - set cert name to NULL and request EST enrollment
leothedragon 0:25fa8795676b 462 if (pv_str_equals(g_lwm2m_name, renewal_data->cert_name,(uint32_t)(strlen(g_lwm2m_name) + 1))) {
leothedragon 0:25fa8795676b 463 SA_PV_LOG_INFO("Attempting to renew LwM2M device certificate\n");
leothedragon 0:25fa8795676b 464 cert_name = NULL;
leothedragon 0:25fa8795676b 465 cert_name_size = 0;
leothedragon 0:25fa8795676b 466 } else {
leothedragon 0:25fa8795676b 467 SA_PV_LOG_INFO("Attempting to renew a custom certificate\n");
leothedragon 0:25fa8795676b 468 cert_name = renewal_data->cert_name;
leothedragon 0:25fa8795676b 469 cert_name_size = strlen(renewal_data->cert_name);
leothedragon 0:25fa8795676b 470 }
leothedragon 0:25fa8795676b 471
leothedragon 0:25fa8795676b 472 // Request a certificate from a CSR via the EST service
leothedragon 0:25fa8795676b 473 est_status = g_est_client->est_request_enrollment(cert_name, cert_name_size, renewal_data->csr, renewal_data->csr_size, est_cb, NULL);
leothedragon 0:25fa8795676b 474 // FIXME: Currently commented out. If we find that the CSR must be persistent only during est_request_enrollment call - uncomment, and this should be the only place we free the CSR
leothedragon 0:25fa8795676b 475 //free(renewal_data->csr);
leothedragon 0:25fa8795676b 476 SA_PV_ERR_RECOVERABLE_RETURN_IF((est_status != EST_STATUS_SUCCESS), certificate_renewal_finish(renewal_data, CE_STATUS_EST_ERROR), "EST request failed");
leothedragon 0:25fa8795676b 477
leothedragon 0:25fa8795676b 478 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS();
leothedragon 0:25fa8795676b 479 }
leothedragon 0:25fa8795676b 480
leothedragon 0:25fa8795676b 481 ce_status_e CertificateEnrollmentClient::schedule_event(event_type_e event_type)
leothedragon 0:25fa8795676b 482 {
leothedragon 0:25fa8795676b 483 int8_t event_status;
leothedragon 0:25fa8795676b 484
leothedragon 0:25fa8795676b 485 arm_event_s event = {
leothedragon 0:25fa8795676b 486 .receiver = handler_id, // ID we got when creating our handler
leothedragon 0:25fa8795676b 487 .sender = 0, // Which tasklet sent us the event is irrelevant to us
leothedragon 0:25fa8795676b 488 .event_type = event_type, // Indicate event type
leothedragon 0:25fa8795676b 489 .event_id = 0, // We currently do not need an ID for a specific event - event type is enough
leothedragon 0:25fa8795676b 490 .data_ptr = 0, // Not needed, data handled in internal structure
leothedragon 0:25fa8795676b 491 .priority = ARM_LIB_LOW_PRIORITY_EVENT, // Application level priority
leothedragon 0:25fa8795676b 492 .event_data = 0, // With one certificate this is irrelevant. If allow multiple certificates, This will be a certificate descriptor (index in a CertificateRenewalDataBase list)
leothedragon 0:25fa8795676b 493 };
leothedragon 0:25fa8795676b 494
leothedragon 0:25fa8795676b 495 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS();
leothedragon 0:25fa8795676b 496
leothedragon 0:25fa8795676b 497 event_status = eventOS_event_send(&event);
leothedragon 0:25fa8795676b 498 SA_PV_ERR_RECOVERABLE_RETURN_IF((event_status < 0), CE_STATUS_OUT_OF_MEMORY, "Error scheduling event");
leothedragon 0:25fa8795676b 499
leothedragon 0:25fa8795676b 500 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS();
leothedragon 0:25fa8795676b 501 return CE_STATUS_SUCCESS;
leothedragon 0:25fa8795676b 502 }
leothedragon 0:25fa8795676b 503
leothedragon 0:25fa8795676b 504 void CertificateEnrollmentClient::est_cb(est_enrollment_result_e result,
leothedragon 0:25fa8795676b 505 cert_chain_context_s *cert_chain,
leothedragon 0:25fa8795676b 506 void *context)
leothedragon 0:25fa8795676b 507 {
leothedragon 0:25fa8795676b 508 ce_status_e status;
leothedragon 0:25fa8795676b 509 SA_PV_LOG_INFO_FUNC_ENTER("result = %d", result);
leothedragon 0:25fa8795676b 510
leothedragon 0:25fa8795676b 511 PV_UNUSED_PARAM(context);
leothedragon 0:25fa8795676b 512 if (result != EST_ENROLLMENT_SUCCESS || cert_chain == NULL) {
leothedragon 0:25fa8795676b 513 return certificate_renewal_finish(current_cert, CE_STATUS_EST_ERROR);
leothedragon 0:25fa8795676b 514 }
leothedragon 0:25fa8795676b 515
leothedragon 0:25fa8795676b 516 // Cert chain remains persistent until g_est_client->free_cert_chain_context is called
leothedragon 0:25fa8795676b 517 current_cert->est_data = cert_chain;
leothedragon 0:25fa8795676b 518
leothedragon 0:25fa8795676b 519 status = schedule_event(CertificateEnrollmentClient::EVENT_TYPE_EST_RESPONDED);
leothedragon 0:25fa8795676b 520 if (status != CE_STATUS_SUCCESS) { // If event scheduling fails - free the chain context and finish the process
leothedragon 0:25fa8795676b 521 SA_PV_LOG_INFO("Error scheduling event");
leothedragon 0:25fa8795676b 522 g_est_client->free_cert_chain_context(current_cert->est_data);
leothedragon 0:25fa8795676b 523
leothedragon 0:25fa8795676b 524 // Make sure we do not keep an invalid pointer
leothedragon 0:25fa8795676b 525 current_cert->est_data = NULL;
leothedragon 0:25fa8795676b 526 certificate_renewal_finish(current_cert, status);
leothedragon 0:25fa8795676b 527 }
leothedragon 0:25fa8795676b 528
leothedragon 0:25fa8795676b 529 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS();
leothedragon 0:25fa8795676b 530 }
leothedragon 0:25fa8795676b 531
leothedragon 0:25fa8795676b 532 void CertificateEnrollmentClient::est_response_process(CertificateRenewalDataBase *renewal_data)
leothedragon 0:25fa8795676b 533 {
leothedragon 0:25fa8795676b 534 ce_status_e ce_status;
leothedragon 0:25fa8795676b 535 ce_renewal_params_s params;
leothedragon 0:25fa8795676b 536 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS();
leothedragon 0:25fa8795676b 537
leothedragon 0:25fa8795676b 538 // Fill params
leothedragon 0:25fa8795676b 539 params.cert_data = renewal_data->est_data;
leothedragon 0:25fa8795676b 540 params.crypto_handle = renewal_data->key_handle;
leothedragon 0:25fa8795676b 541
leothedragon 0:25fa8795676b 542 // Perform a safe renewal
leothedragon 0:25fa8795676b 543 ce_status = ce_safe_renewal(renewal_data->cert_name, &params);
leothedragon 0:25fa8795676b 544
leothedragon 0:25fa8795676b 545 // Free the est chain. Do not free in the destructor, we'd rather free it as soon as possible
leothedragon 0:25fa8795676b 546 g_est_client->free_cert_chain_context(renewal_data->est_data);
leothedragon 0:25fa8795676b 547 renewal_data->est_data = NULL;
leothedragon 0:25fa8795676b 548
leothedragon 0:25fa8795676b 549 // Done!
leothedragon 0:25fa8795676b 550 certificate_renewal_finish(renewal_data, ce_status);
leothedragon 0:25fa8795676b 551 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS();
leothedragon 0:25fa8795676b 552 }
leothedragon 0:25fa8795676b 553
leothedragon 0:25fa8795676b 554 void CertificateEnrollmentClient::certificate_renewal_finish(CertificateRenewalDataBase *renewal_data, ce_status_e exit_status)
leothedragon 0:25fa8795676b 555 {
leothedragon 0:25fa8795676b 556 palStatus_t pal_status;
leothedragon 0:25fa8795676b 557 SA_PV_LOG_INFO_FUNC_ENTER("exit_status = %d", exit_status);
leothedragon 0:25fa8795676b 558
leothedragon 0:25fa8795676b 559 // Don't leave an invalid global pointer
leothedragon 0:25fa8795676b 560 current_cert = NULL;
leothedragon 0:25fa8795676b 561
leothedragon 0:25fa8795676b 562 // Note: release of the mutex is before the deletion of the object (which holds the allocated cert_name)
leothedragon 0:25fa8795676b 563 // and before the user callback is invoked (so that the user may call the renewal API successfully from within his callback)
leothedragon 0:25fa8795676b 564 pal_status = pal_osSemaphoreRelease(g_renewal_sem);
leothedragon 0:25fa8795676b 565 if (PAL_SUCCESS != pal_status) { //
leothedragon 0:25fa8795676b 566 exit_status = CE_STATUS_ERROR;
leothedragon 0:25fa8795676b 567 }
leothedragon 0:25fa8795676b 568
leothedragon 0:25fa8795676b 569 // At this point, new device requests may be made and the global pointer CertificateEnrollmentClient::current_cert may be changed.
leothedragon 0:25fa8795676b 570 // Therefore, we use the renewal_data pointer that was past as a parameter to this function
leothedragon 0:25fa8795676b 571 // New server requests will not be made until after this function returns since the response to the server is enqueued into the event loop by renewal_data->finish()
leothedragon 0:25fa8795676b 572 // and it is guaranteed that the server will not send another request until it receives a response.
leothedragon 0:25fa8795676b 573 renewal_data->finish(exit_status);
leothedragon 0:25fa8795676b 574
leothedragon 0:25fa8795676b 575 delete renewal_data;
leothedragon 0:25fa8795676b 576
leothedragon 0:25fa8795676b 577 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS();
leothedragon 0:25fa8795676b 578 }
leothedragon 0:25fa8795676b 579
leothedragon 0:25fa8795676b 580 #ifdef CERT_RENEWAL_TEST
leothedragon 0:25fa8795676b 581 void CertificateEnrollmentClient::testonly_certificate_renewal_post(void *arg)
leothedragon 0:25fa8795676b 582 {
leothedragon 0:25fa8795676b 583 return certificate_renewal_post(arg);
leothedragon 0:25fa8795676b 584 }
leothedragon 0:25fa8795676b 585
leothedragon 0:25fa8795676b 586
leothedragon 0:25fa8795676b 587 #endif // CERT_RENEWAL_TEST