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.
Dependencies: FXAS21002 FXOS8700Q
EstClient.cpp
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 #define __STDC_FORMAT_MACROS 00020 #include <inttypes.h> 00021 00022 #include "include/ConnectorClient.h" 00023 #include "include/EstClient.h" 00024 #include "mbed-trace/mbed_trace.h" 00025 #include "mbed-client-libservice/common_functions.h" 00026 00027 #include <stdio.h> 00028 #include <stdlib.h> 00029 00030 #define TRACE_GROUP "est" 00031 00032 struct enrollment_context_s { 00033 est_enrollment_result_cb result_cb; 00034 uint8_t *data; 00035 size_t data_size; 00036 void* context; 00037 }; 00038 00039 #define EST_SEN_LWM2M "est/sen" 00040 #define EST_SEN_URI_FORMAT "est/%.*s/sen" 00041 00042 #define EST_CERT_CHAIN_VERSION 1 00043 00044 EstClient::EstClient(ConnectorClient& connector_client) 00045 :_connector_client(connector_client) 00046 { 00047 00048 } 00049 00050 00051 EstClient::~EstClient() 00052 { 00053 } 00054 00055 est_status_e EstClient::est_request_enrollment(const char *cert_name, 00056 const size_t cert_name_length, 00057 uint8_t *csr, 00058 const size_t csr_length, 00059 est_enrollment_result_cb result_cb, 00060 void *context) const 00061 { 00062 if (csr == NULL || csr_length == 0 || result_cb == NULL) { 00063 return EST_STATUS_INVALID_PARAMETERS; 00064 } 00065 00066 if (_connector_client.m2m_interface() == NULL) { 00067 return EST_STATUS_INVALID_PARAMETERS; 00068 } 00069 00070 enrollment_context_s *ctx = (enrollment_context_s*)malloc(sizeof(enrollment_context_s)); 00071 if (ctx == NULL) { 00072 return EST_STATUS_MEMORY_ALLOCATION_FAILURE; 00073 } 00074 00075 char *uri = make_est_uri(cert_name, cert_name_length); 00076 if (uri == NULL) { 00077 free(ctx); 00078 return EST_STATUS_MEMORY_ALLOCATION_FAILURE; 00079 } 00080 00081 ctx->result_cb = result_cb; 00082 ctx->context = context; 00083 ctx->data = NULL; 00084 ctx->data_size = 0; 00085 00086 _connector_client.m2m_interface()->post_data_request(uri, 00087 false, 00088 csr_length, 00089 csr, 00090 EstClient::est_post_data_cb, 00091 EstClient::est_post_data_error_cb, 00092 (void*)ctx); 00093 00094 free(uri); 00095 00096 return EST_STATUS_SUCCESS; 00097 } 00098 00099 char* EstClient::make_est_uri(const char *cert_name, 00100 const size_t cert_name_length) 00101 { 00102 char *uri = NULL; 00103 size_t uri_len = 0; 00104 if (cert_name == NULL) { 00105 // LwM2M certificate 00106 uri = (char*)malloc(sizeof(EST_SEN_LWM2M)); 00107 if (uri != NULL) { 00108 strcpy(uri, EST_SEN_LWM2M); 00109 } 00110 } 00111 else { 00112 // User certificate 00113 uri_len = snprintf(NULL, 0, EST_SEN_URI_FORMAT, (int)cert_name_length, cert_name); 00114 uri_len++; // For null terminator 00115 uri = (char*)calloc(uri_len, sizeof(char)); 00116 if (uri != NULL) { 00117 snprintf(uri, uri_len, EST_SEN_URI_FORMAT, (int)cert_name_length, cert_name); 00118 } 00119 } 00120 return uri; 00121 } 00122 00123 void EstClient::est_post_data_cb(const uint8_t *buffer, 00124 size_t buffer_size, 00125 size_t total_size, 00126 bool last_block, 00127 void *context) 00128 { 00129 enrollment_context_s *enrollment_context = static_cast<enrollment_context_s*>(context); 00130 (void)total_size; 00131 assert(enrollment_context); 00132 00133 // Append new buffer to payload 00134 size_t new_size = enrollment_context->data_size + buffer_size; 00135 uint8_t *new_buffer = (uint8_t*)malloc(new_size); 00136 if (!new_buffer) { 00137 // Memory error! 00138 return; 00139 } 00140 00141 // Copy old data to start of buffer 00142 if (enrollment_context->data) { 00143 memcpy(new_buffer, enrollment_context->data, enrollment_context->data_size); 00144 free(enrollment_context->data); 00145 } 00146 00147 // Copy new data to buffer 00148 memcpy(new_buffer + enrollment_context->data_size, buffer, buffer_size); 00149 00150 enrollment_context->data = new_buffer; 00151 enrollment_context->data_size = new_size; 00152 00153 if (last_block) { 00154 cert_chain_context_s *cert_ctx = parse_cert_chain(enrollment_context->data, enrollment_context->data_size); 00155 if (cert_ctx != NULL) { 00156 enrollment_context->result_cb(EST_ENROLLMENT_SUCCESS, cert_ctx, enrollment_context->context); 00157 } 00158 else { 00159 enrollment_context->result_cb(EST_ENROLLMENT_FAILURE, NULL, enrollment_context->context); 00160 } 00161 00162 free(enrollment_context); 00163 } 00164 00165 } 00166 00167 void EstClient::est_post_data_error_cb(get_data_req_error_t error_code, 00168 void *context) 00169 { 00170 enrollment_context_s *enrollment_context = static_cast<enrollment_context_s*>(context); 00171 assert(enrollment_context); 00172 enrollment_context->result_cb(EST_ENROLLMENT_FAILURE, NULL, enrollment_context->context); 00173 free(enrollment_context); 00174 } 00175 00176 cert_chain_context_s* EstClient::parse_cert_chain(uint8_t *cert_chain_data, 00177 uint16_t cert_chain_data_len) 00178 { 00179 assert(cert_chain_data); 00180 assert(cert_chain_data_len > 0); 00181 00182 uint8_t *ptr = cert_chain_data; 00183 cert_chain_context_s *context = (cert_chain_context_s*)malloc(sizeof(cert_chain_context_s)); 00184 00185 if (context != NULL) { 00186 bool success = true; 00187 context->cert_data_context = ptr; 00188 uint8_t version = *ptr++; 00189 context->chain_length = *ptr++; 00190 cert_context_s **next_context_ptr = &context->certs; 00191 00192 // Check if unknown version 00193 if (version != EST_CERT_CHAIN_VERSION) { 00194 success = false; 00195 } 00196 00197 // Check overflow 00198 if (success && ptr - cert_chain_data > cert_chain_data_len) { 00199 success = false; 00200 context->chain_length = 0; 00201 } 00202 00203 if (success) { 00204 for (int i = 0; i < context->chain_length; i++) { 00205 // Parse certificate length (2 bytes) 00206 uint16_t cert_len = common_read_16_bit(ptr); 00207 ptr += 2; 00208 // Check overflow 00209 if (ptr - cert_chain_data > cert_chain_data_len) { 00210 success = false; 00211 break; 00212 } 00213 00214 // Allocate new certificate context 00215 *next_context_ptr = (cert_context_s*)malloc(sizeof(cert_context_s)); 00216 if (*next_context_ptr == NULL) { 00217 // Error 00218 success = false; 00219 break; 00220 } 00221 00222 // Set cert pointer to correct position in data 00223 (*next_context_ptr)->cert_length = cert_len; 00224 (*next_context_ptr)->cert = ptr; 00225 00226 ptr += cert_len; 00227 00228 // Check overflow 00229 if (ptr - cert_chain_data > cert_chain_data_len) { 00230 success = false; 00231 free(*next_context_ptr); 00232 break; 00233 } 00234 00235 next_context_ptr = &((*next_context_ptr)->next); 00236 } 00237 *next_context_ptr = NULL; 00238 } 00239 00240 if (!success) { 00241 free_cert_chain_context(context); 00242 context = NULL; 00243 } 00244 } 00245 00246 return context; 00247 } 00248 00249 void EstClient::free_cert_chain_context(cert_chain_context_s *context) { 00250 if (context) { 00251 cert_context_s *next_cert = context->certs; 00252 while (next_cert != NULL) { 00253 cert_context_s *temp = next_cert->next; 00254 // Free each cert context, no need to free the cert data in 00255 // next_cert->cert because it points inside context->cert_data_context 00256 // which is free'd last 00257 free(next_cert); 00258 next_cert = temp; 00259 } 00260 free(context->cert_data_context); 00261 free(context); 00262 } 00263 }
Generated on Tue Jul 12 2022 20:20:59 by
