Fork for workshops

Committer:
JimCarver
Date:
Fri Oct 12 21:22:49 2018 +0000
Revision:
0:6b753f761943
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JimCarver 0:6b753f761943 1 // ----------------------------------------------------------------------------
JimCarver 0:6b753f761943 2 // Copyright 2016-2017 ARM Ltd.
JimCarver 0:6b753f761943 3 //
JimCarver 0:6b753f761943 4 // SPDX-License-Identifier: Apache-2.0
JimCarver 0:6b753f761943 5 //
JimCarver 0:6b753f761943 6 // Licensed under the Apache License, Version 2.0 (the "License");
JimCarver 0:6b753f761943 7 // you may not use this file except in compliance with the License.
JimCarver 0:6b753f761943 8 // You may obtain a copy of the License at
JimCarver 0:6b753f761943 9 //
JimCarver 0:6b753f761943 10 // http://www.apache.org/licenses/LICENSE-2.0
JimCarver 0:6b753f761943 11 //
JimCarver 0:6b753f761943 12 // Unless required by applicable law or agreed to in writing, software
JimCarver 0:6b753f761943 13 // distributed under the License is distributed on an "AS IS" BASIS,
JimCarver 0:6b753f761943 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
JimCarver 0:6b753f761943 15 // See the License for the specific language governing permissions and
JimCarver 0:6b753f761943 16 // limitations under the License.
JimCarver 0:6b753f761943 17 // ----------------------------------------------------------------------------
JimCarver 0:6b753f761943 18
JimCarver 0:6b753f761943 19 // fixup the compilation on ARMCC for PRId32
JimCarver 0:6b753f761943 20 #define __STDC_FORMAT_MACROS
JimCarver 0:6b753f761943 21 #include <inttypes.h>
JimCarver 0:6b753f761943 22
JimCarver 0:6b753f761943 23 #include "include/ConnectorClient.h"
JimCarver 0:6b753f761943 24 #include "include/CloudClientStorage.h"
JimCarver 0:6b753f761943 25 #include "include/CertificateParser.h"
JimCarver 0:6b753f761943 26 #include "MbedCloudClient.h"
JimCarver 0:6b753f761943 27 #include "mbed-client/m2mconstants.h"
JimCarver 0:6b753f761943 28 #include "mbed-client/m2minterfacefactory.h"
JimCarver 0:6b753f761943 29 #include "mbed-client/m2mdevice.h"
JimCarver 0:6b753f761943 30 #include "mbed-client/m2mconstants.h"
JimCarver 0:6b753f761943 31 #include "mbed-trace/mbed_trace.h"
JimCarver 0:6b753f761943 32 #include "factory_configurator_client.h"
JimCarver 0:6b753f761943 33 #include "key_config_manager.h"
JimCarver 0:6b753f761943 34 #include "mbed-client/uriqueryparser.h"
JimCarver 0:6b753f761943 35
JimCarver 0:6b753f761943 36 #include <assert.h>
JimCarver 0:6b753f761943 37 #include <string>
JimCarver 0:6b753f761943 38 #include <stdio.h>
JimCarver 0:6b753f761943 39
JimCarver 0:6b753f761943 40 #include "ns_hal_init.h"
JimCarver 0:6b753f761943 41
JimCarver 0:6b753f761943 42 #ifdef MBED_CONF_MBED_CLIENT_EVENT_LOOP_SIZE
JimCarver 0:6b753f761943 43 #define MBED_CLIENT_EVENT_LOOP_SIZE MBED_CONF_MBED_CLIENT_EVENT_LOOP_SIZE
JimCarver 0:6b753f761943 44 #else
JimCarver 0:6b753f761943 45 #define MBED_CLIENT_EVENT_LOOP_SIZE 1024
JimCarver 0:6b753f761943 46 #endif
JimCarver 0:6b753f761943 47
JimCarver 0:6b753f761943 48 #define TRACE_GROUP "mClt"
JimCarver 0:6b753f761943 49
JimCarver 0:6b753f761943 50 #define INTERNAL_ENDPOINT_PARAM "&iep="
JimCarver 0:6b753f761943 51 #define DEFAULT_ENDPOINT "endpoint"
JimCarver 0:6b753f761943 52 #define INTERFACE_ERROR "Client interface is not created. Restart"
JimCarver 0:6b753f761943 53 #define CREDENTIAL_ERROR "Failed to read credentials from storage"
JimCarver 0:6b753f761943 54 #define DEVICE_NOT_PROVISIONED "Device not provisioned"
JimCarver 0:6b753f761943 55 #define ERROR_NO_MEMORY "Not enough memory to store LWM2M credentials"
JimCarver 0:6b753f761943 56
JimCarver 0:6b753f761943 57 #ifndef MBED_CLIENT_DISABLE_EST_FEATURE
JimCarver 0:6b753f761943 58 #define ERROR_EST_ENROLLMENT_REQUEST_FAILED "EST enrollment request failed"
JimCarver 0:6b753f761943 59 #define LWM2M_CSR_SUBJECT_FORMAT "L=%s,OU=%s,CN=%s"
JimCarver 0:6b753f761943 60 #endif
JimCarver 0:6b753f761943 61
JimCarver 0:6b753f761943 62 // XXX: nothing here yet
JimCarver 0:6b753f761943 63 class EventData {
JimCarver 0:6b753f761943 64
JimCarver 0:6b753f761943 65 };
JimCarver 0:6b753f761943 66
JimCarver 0:6b753f761943 67 static int read_callback_helper(const char *key, void *buffer, size_t *buffer_len)
JimCarver 0:6b753f761943 68 {
JimCarver 0:6b753f761943 69 size_t cert_size = 0;
JimCarver 0:6b753f761943 70 if (strcmp(key, g_fcc_lwm2m_device_private_key_name) == 0 ||
JimCarver 0:6b753f761943 71 strcmp(key, g_fcc_bootstrap_device_private_key_name) == 0) {
JimCarver 0:6b753f761943 72 if (ccs_item_size(key, buffer_len, CCS_PRIVATE_KEY_ITEM) != CCS_STATUS_SUCCESS) {
JimCarver 0:6b753f761943 73 *buffer_len = 0;
JimCarver 0:6b753f761943 74 return CCS_STATUS_ERROR;
JimCarver 0:6b753f761943 75 }
JimCarver 0:6b753f761943 76
JimCarver 0:6b753f761943 77 if (ccs_get_item(key, (uint8_t*)buffer, *buffer_len, &cert_size, CCS_PRIVATE_KEY_ITEM) != CCS_STATUS_SUCCESS) {
JimCarver 0:6b753f761943 78 *buffer_len = 0;
JimCarver 0:6b753f761943 79 return CCS_STATUS_ERROR;
JimCarver 0:6b753f761943 80 }
JimCarver 0:6b753f761943 81 } else {
JimCarver 0:6b753f761943 82 if (ccs_item_size(key, buffer_len, CCS_CERTIFICATE_ITEM) != CCS_STATUS_SUCCESS) {
JimCarver 0:6b753f761943 83 *buffer_len = 0;
JimCarver 0:6b753f761943 84 return CCS_STATUS_ERROR;
JimCarver 0:6b753f761943 85 }
JimCarver 0:6b753f761943 86
JimCarver 0:6b753f761943 87 if (ccs_get_item(key, (uint8_t*)buffer, *buffer_len, &cert_size, CCS_CERTIFICATE_ITEM) != CCS_STATUS_SUCCESS) {
JimCarver 0:6b753f761943 88 *buffer_len = 0;
JimCarver 0:6b753f761943 89 return CCS_STATUS_ERROR;
JimCarver 0:6b753f761943 90 }
JimCarver 0:6b753f761943 91 }
JimCarver 0:6b753f761943 92
JimCarver 0:6b753f761943 93 *buffer_len = cert_size;
JimCarver 0:6b753f761943 94
JimCarver 0:6b753f761943 95 return CCS_STATUS_SUCCESS;
JimCarver 0:6b753f761943 96 }
JimCarver 0:6b753f761943 97
JimCarver 0:6b753f761943 98 static bool write_security_object_data_to_kcm(const M2MResourceBase& resource, const uint8_t *buffer, const size_t buffer_size, void */*client_args*/)
JimCarver 0:6b753f761943 99 {
JimCarver 0:6b753f761943 100 ccs_status_e status = CCS_STATUS_ERROR;
JimCarver 0:6b753f761943 101 uint32_t resource_id = resource.name_id();
JimCarver 0:6b753f761943 102 uint16_t object_instance_id = resource.object_instance_id();
JimCarver 0:6b753f761943 103
JimCarver 0:6b753f761943 104 switch (resource_id) {
JimCarver 0:6b753f761943 105 case M2MSecurity::PublicKey:
JimCarver 0:6b753f761943 106 if (object_instance_id == M2MSecurity::Bootstrap) {
JimCarver 0:6b753f761943 107 ccs_delete_item(g_fcc_bootstrap_device_certificate_name, CCS_CERTIFICATE_ITEM);
JimCarver 0:6b753f761943 108 status = ccs_set_item(g_fcc_bootstrap_device_certificate_name, buffer, buffer_size, CCS_CERTIFICATE_ITEM);
JimCarver 0:6b753f761943 109 } else {
JimCarver 0:6b753f761943 110 ccs_delete_item(g_fcc_lwm2m_device_certificate_name, CCS_CERTIFICATE_ITEM);
JimCarver 0:6b753f761943 111 status = ccs_set_item(g_fcc_lwm2m_device_certificate_name, buffer, buffer_size, CCS_CERTIFICATE_ITEM);
JimCarver 0:6b753f761943 112 }
JimCarver 0:6b753f761943 113 break;
JimCarver 0:6b753f761943 114
JimCarver 0:6b753f761943 115 case M2MSecurity::ServerPublicKey:
JimCarver 0:6b753f761943 116 if (object_instance_id == M2MSecurity::Bootstrap) {
JimCarver 0:6b753f761943 117 ccs_delete_item(g_fcc_bootstrap_server_ca_certificate_name, CCS_CERTIFICATE_ITEM);
JimCarver 0:6b753f761943 118 status = ccs_set_item(g_fcc_bootstrap_server_ca_certificate_name, buffer, buffer_size, CCS_CERTIFICATE_ITEM);
JimCarver 0:6b753f761943 119 } else {
JimCarver 0:6b753f761943 120 ccs_delete_item(g_fcc_lwm2m_server_ca_certificate_name, CCS_CERTIFICATE_ITEM);
JimCarver 0:6b753f761943 121 status = ccs_set_item(g_fcc_lwm2m_server_ca_certificate_name, buffer, buffer_size, CCS_CERTIFICATE_ITEM);
JimCarver 0:6b753f761943 122 }
JimCarver 0:6b753f761943 123 break;
JimCarver 0:6b753f761943 124
JimCarver 0:6b753f761943 125 case M2MSecurity::Secretkey:
JimCarver 0:6b753f761943 126 if (object_instance_id == M2MSecurity::Bootstrap) {
JimCarver 0:6b753f761943 127 ccs_delete_item(g_fcc_bootstrap_device_private_key_name, CCS_PRIVATE_KEY_ITEM);
JimCarver 0:6b753f761943 128 status = ccs_set_item(g_fcc_bootstrap_device_private_key_name, buffer, buffer_size, CCS_PRIVATE_KEY_ITEM);
JimCarver 0:6b753f761943 129 } else {
JimCarver 0:6b753f761943 130 ccs_delete_item(g_fcc_lwm2m_device_private_key_name, CCS_PRIVATE_KEY_ITEM);
JimCarver 0:6b753f761943 131 status = ccs_set_item(g_fcc_lwm2m_device_private_key_name, buffer, buffer_size, CCS_PRIVATE_KEY_ITEM);
JimCarver 0:6b753f761943 132 }
JimCarver 0:6b753f761943 133 break;
JimCarver 0:6b753f761943 134
JimCarver 0:6b753f761943 135 default:
JimCarver 0:6b753f761943 136 break;
JimCarver 0:6b753f761943 137 }
JimCarver 0:6b753f761943 138
JimCarver 0:6b753f761943 139 return (status == CCS_STATUS_SUCCESS) ? true : false;
JimCarver 0:6b753f761943 140 }
JimCarver 0:6b753f761943 141
JimCarver 0:6b753f761943 142 static int read_security_object_data_from_kcm(const M2MResourceBase& resource, void *buffer, size_t *buffer_len, void */*client_args*/)
JimCarver 0:6b753f761943 143 {
JimCarver 0:6b753f761943 144 uint32_t resource_id = resource.name_id();
JimCarver 0:6b753f761943 145 uint16_t object_instance_id = resource.object_instance_id();
JimCarver 0:6b753f761943 146 switch (resource_id) {
JimCarver 0:6b753f761943 147 case M2MSecurity::PublicKey:
JimCarver 0:6b753f761943 148 if (object_instance_id == M2MSecurity::Bootstrap) {
JimCarver 0:6b753f761943 149 return read_callback_helper(g_fcc_bootstrap_device_certificate_name, buffer, buffer_len);
JimCarver 0:6b753f761943 150 } else {
JimCarver 0:6b753f761943 151 return read_callback_helper(g_fcc_lwm2m_device_certificate_name, buffer, buffer_len);
JimCarver 0:6b753f761943 152 }
JimCarver 0:6b753f761943 153
JimCarver 0:6b753f761943 154 case M2MSecurity::ServerPublicKey:
JimCarver 0:6b753f761943 155 if (object_instance_id == M2MSecurity::Bootstrap) {
JimCarver 0:6b753f761943 156 return read_callback_helper(g_fcc_bootstrap_server_ca_certificate_name, buffer, buffer_len);
JimCarver 0:6b753f761943 157 } else {
JimCarver 0:6b753f761943 158 return read_callback_helper(g_fcc_lwm2m_server_ca_certificate_name, buffer, buffer_len);
JimCarver 0:6b753f761943 159 }
JimCarver 0:6b753f761943 160
JimCarver 0:6b753f761943 161 case M2MSecurity::Secretkey:
JimCarver 0:6b753f761943 162 if (object_instance_id == M2MSecurity::Bootstrap) {
JimCarver 0:6b753f761943 163 return read_callback_helper(g_fcc_bootstrap_device_private_key_name, buffer, buffer_len);
JimCarver 0:6b753f761943 164 } else {
JimCarver 0:6b753f761943 165 return read_callback_helper(g_fcc_lwm2m_device_private_key_name, buffer, buffer_len);
JimCarver 0:6b753f761943 166 }
JimCarver 0:6b753f761943 167
JimCarver 0:6b753f761943 168 default:
JimCarver 0:6b753f761943 169 break;
JimCarver 0:6b753f761943 170 }
JimCarver 0:6b753f761943 171
JimCarver 0:6b753f761943 172 return CCS_STATUS_ERROR;
JimCarver 0:6b753f761943 173 }
JimCarver 0:6b753f761943 174
JimCarver 0:6b753f761943 175 static int open_certificate_chain_callback(const M2MResourceBase& resource, void */*buffer*/, size_t *chain_size, void *client_args)
JimCarver 0:6b753f761943 176 {
JimCarver 0:6b753f761943 177 void *handle = NULL;
JimCarver 0:6b753f761943 178 uint16_t object_instance_id = resource.object_instance_id();
JimCarver 0:6b753f761943 179 ConnectorClient *client = (ConnectorClient*)client_args;
JimCarver 0:6b753f761943 180 if (object_instance_id == M2MSecurity::Bootstrap) {
JimCarver 0:6b753f761943 181 handle = ccs_open_certificate_chain(g_fcc_bootstrap_device_certificate_name, chain_size);
JimCarver 0:6b753f761943 182 client->set_certificate_chain_handle(handle);
JimCarver 0:6b753f761943 183 } else {
JimCarver 0:6b753f761943 184 handle = ccs_open_certificate_chain(g_fcc_lwm2m_device_certificate_name, chain_size);
JimCarver 0:6b753f761943 185 client->set_certificate_chain_handle(handle);
JimCarver 0:6b753f761943 186 }
JimCarver 0:6b753f761943 187
JimCarver 0:6b753f761943 188 return (handle) ? CCS_STATUS_SUCCESS : CCS_STATUS_ERROR;
JimCarver 0:6b753f761943 189 }
JimCarver 0:6b753f761943 190
JimCarver 0:6b753f761943 191 static int read_certificate_chain_callback(const M2MResourceBase& /*resource*/, void *buffer, size_t *buffer_len, void *client_args)
JimCarver 0:6b753f761943 192 {
JimCarver 0:6b753f761943 193 ConnectorClient *client = (ConnectorClient*) client_args;
JimCarver 0:6b753f761943 194 ccs_status_e status = CCS_STATUS_ERROR;
JimCarver 0:6b753f761943 195 if (client->certificate_chain_handle()) {
JimCarver 0:6b753f761943 196 status = ccs_get_next_cert_chain(client->certificate_chain_handle(), buffer, buffer_len);
JimCarver 0:6b753f761943 197 }
JimCarver 0:6b753f761943 198
JimCarver 0:6b753f761943 199 return status;
JimCarver 0:6b753f761943 200 }
JimCarver 0:6b753f761943 201
JimCarver 0:6b753f761943 202 static int close_certificate_chain_callback(const M2MResourceBase& /*resource*/, void */*buffer*/, size_t *, void *client_args)
JimCarver 0:6b753f761943 203 {
JimCarver 0:6b753f761943 204 ccs_status_e status = CCS_STATUS_ERROR;
JimCarver 0:6b753f761943 205 ConnectorClient *client = (ConnectorClient*) client_args;
JimCarver 0:6b753f761943 206 if (client->certificate_chain_handle()) {
JimCarver 0:6b753f761943 207 status = ccs_close_certificate_chain(client->certificate_chain_handle());
JimCarver 0:6b753f761943 208 client->set_certificate_chain_handle(NULL);
JimCarver 0:6b753f761943 209 }
JimCarver 0:6b753f761943 210 return status;
JimCarver 0:6b753f761943 211 }
JimCarver 0:6b753f761943 212
JimCarver 0:6b753f761943 213 ConnectorClient::ConnectorClient(ConnectorClientCallback* callback)
JimCarver 0:6b753f761943 214 : _callback(callback),
JimCarver 0:6b753f761943 215 _current_state(State_Bootstrap_Start),
JimCarver 0:6b753f761943 216 _event_generated(false), _state_engine_running(false),
JimCarver 0:6b753f761943 217 _interface(NULL), _security(NULL),
JimCarver 0:6b753f761943 218 _endpoint_info(M2MSecurity::Certificate), _client_objs(NULL),
JimCarver 0:6b753f761943 219 _rebootstrap_timer(*this), _bootstrap_security_instance(1), _lwm2m_security_instance(0), _certificate_chain_handle(NULL)
JimCarver 0:6b753f761943 220 {
JimCarver 0:6b753f761943 221 assert(_callback != NULL);
JimCarver 0:6b753f761943 222
JimCarver 0:6b753f761943 223 // XXX: this initialization sequence needs more work, as doing the allocations
JimCarver 0:6b753f761943 224 // and static initializations from constructor is really troublesome.
JimCarver 0:6b753f761943 225 // All this needs to be moved to the separate setup() call.
JimCarver 0:6b753f761943 226
JimCarver 0:6b753f761943 227 // The ns_hal_init() needs to be called by someone before create_interface(),
JimCarver 0:6b753f761943 228 // as it will also initialize the tasklet.
JimCarver 0:6b753f761943 229 ns_hal_init(NULL, MBED_CLIENT_EVENT_LOOP_SIZE, NULL, NULL);
JimCarver 0:6b753f761943 230
JimCarver 0:6b753f761943 231 // Create the lwm2m server security object we need always
JimCarver 0:6b753f761943 232 _security = M2MInterfaceFactory::create_security(M2MSecurity::M2MServer);
JimCarver 0:6b753f761943 233 _interface = M2MInterfaceFactory::create_interface(*this,
JimCarver 0:6b753f761943 234 DEFAULT_ENDPOINT, // endpoint name string
JimCarver 0:6b753f761943 235 MBED_CLOUD_CLIENT_ENDPOINT_TYPE, // endpoint type string
JimCarver 0:6b753f761943 236 MBED_CLOUD_CLIENT_LIFETIME, // lifetime
JimCarver 0:6b753f761943 237 MBED_CLOUD_CLIENT_LISTEN_PORT, // listen port
JimCarver 0:6b753f761943 238 _endpoint_info.account_id, // domain string
JimCarver 0:6b753f761943 239 transport_mode(), // binding mode
JimCarver 0:6b753f761943 240 M2MInterface::LwIP_IPv4); // network stack
JimCarver 0:6b753f761943 241
JimCarver 0:6b753f761943 242 initialize_storage();
JimCarver 0:6b753f761943 243 }
JimCarver 0:6b753f761943 244
JimCarver 0:6b753f761943 245
JimCarver 0:6b753f761943 246 ConnectorClient::~ConnectorClient()
JimCarver 0:6b753f761943 247 {
JimCarver 0:6b753f761943 248 uninitialize_storage();
JimCarver 0:6b753f761943 249 M2MDevice::delete_instance();
JimCarver 0:6b753f761943 250 M2MSecurity::delete_instance();
JimCarver 0:6b753f761943 251 delete _interface;
JimCarver 0:6b753f761943 252 }
JimCarver 0:6b753f761943 253
JimCarver 0:6b753f761943 254 void ConnectorClient::start_bootstrap()
JimCarver 0:6b753f761943 255 {
JimCarver 0:6b753f761943 256 tr_debug("ConnectorClient::start_bootstrap()");
JimCarver 0:6b753f761943 257 assert(_callback != NULL);
JimCarver 0:6b753f761943 258 init_security_object();
JimCarver 0:6b753f761943 259 // Stop rebootstrap timer if it was running
JimCarver 0:6b753f761943 260 _rebootstrap_timer.stop_timer();
JimCarver 0:6b753f761943 261
JimCarver 0:6b753f761943 262 if (create_bootstrap_object()) {
JimCarver 0:6b753f761943 263 _interface->update_endpoint(_endpoint_info.endpoint_name);
JimCarver 0:6b753f761943 264 _interface->update_domain(_endpoint_info.account_id);
JimCarver 0:6b753f761943 265 internal_event(State_Bootstrap_Start);
JimCarver 0:6b753f761943 266 } else {
JimCarver 0:6b753f761943 267 tr_error("ConnectorClient::start_bootstrap() - bootstrap object fail");
JimCarver 0:6b753f761943 268 }
JimCarver 0:6b753f761943 269 state_engine();
JimCarver 0:6b753f761943 270 }
JimCarver 0:6b753f761943 271
JimCarver 0:6b753f761943 272 void ConnectorClient::start_registration(M2MBaseList* client_objs)
JimCarver 0:6b753f761943 273 {
JimCarver 0:6b753f761943 274 tr_debug("ConnectorClient::start_registration()");
JimCarver 0:6b753f761943 275 assert(_callback != NULL);
JimCarver 0:6b753f761943 276 init_security_object();
JimCarver 0:6b753f761943 277 _client_objs = client_objs;
JimCarver 0:6b753f761943 278
JimCarver 0:6b753f761943 279 // XXX: actually this call should be external_event() to match the pattern used in other m2m classes
JimCarver 0:6b753f761943 280 create_register_object();
JimCarver 0:6b753f761943 281 if(_security->get_security_instance_id(M2MSecurity::M2MServer) >= 0) {
JimCarver 0:6b753f761943 282 _interface->update_endpoint(_endpoint_info.endpoint_name);
JimCarver 0:6b753f761943 283 _interface->update_domain(_endpoint_info.account_id);
JimCarver 0:6b753f761943 284 internal_event(State_Registration_Start);
JimCarver 0:6b753f761943 285 } else {
JimCarver 0:6b753f761943 286 tr_error("ConnectorClient::start_registration(): failed to create objs");
JimCarver 0:6b753f761943 287 _callback->connector_error(M2MInterface::InvalidParameters, INTERFACE_ERROR);
JimCarver 0:6b753f761943 288 }
JimCarver 0:6b753f761943 289 state_engine();
JimCarver 0:6b753f761943 290 }
JimCarver 0:6b753f761943 291
JimCarver 0:6b753f761943 292 M2MInterface * ConnectorClient::m2m_interface()
JimCarver 0:6b753f761943 293 {
JimCarver 0:6b753f761943 294 return _interface;
JimCarver 0:6b753f761943 295 }
JimCarver 0:6b753f761943 296
JimCarver 0:6b753f761943 297 void ConnectorClient::update_registration()
JimCarver 0:6b753f761943 298 {
JimCarver 0:6b753f761943 299 if(_interface && _security && _security->get_security_instance_id(M2MSecurity::M2MServer) >= 0) {
JimCarver 0:6b753f761943 300 if (_client_objs != NULL) {
JimCarver 0:6b753f761943 301 _interface->update_registration(_security, *_client_objs);
JimCarver 0:6b753f761943 302 }
JimCarver 0:6b753f761943 303 else {
JimCarver 0:6b753f761943 304 _interface->update_registration(_security);
JimCarver 0:6b753f761943 305 }
JimCarver 0:6b753f761943 306 }
JimCarver 0:6b753f761943 307 }
JimCarver 0:6b753f761943 308
JimCarver 0:6b753f761943 309 // generates an internal event. called from within a state
JimCarver 0:6b753f761943 310 // function to transition to a new state
JimCarver 0:6b753f761943 311 void ConnectorClient::internal_event(StartupSubStateRegistration new_state)
JimCarver 0:6b753f761943 312 {
JimCarver 0:6b753f761943 313 tr_debug("ConnectorClient::internal_event: state: %d -> %d", _current_state, new_state);
JimCarver 0:6b753f761943 314 _event_generated = true;
JimCarver 0:6b753f761943 315 _current_state = new_state;
JimCarver 0:6b753f761943 316
JimCarver 0:6b753f761943 317 // Avoid recursive chain which eats too much of stack
JimCarver 0:6b753f761943 318 if (!_state_engine_running) {
JimCarver 0:6b753f761943 319 state_engine();
JimCarver 0:6b753f761943 320 }
JimCarver 0:6b753f761943 321 }
JimCarver 0:6b753f761943 322
JimCarver 0:6b753f761943 323 // the state engine executes the state machine states
JimCarver 0:6b753f761943 324 void ConnectorClient::state_engine(void)
JimCarver 0:6b753f761943 325 {
JimCarver 0:6b753f761943 326 tr_debug("ConnectorClient::state_engine");
JimCarver 0:6b753f761943 327
JimCarver 0:6b753f761943 328 // this simple flagging gets rid of recursive calls to this method
JimCarver 0:6b753f761943 329 _state_engine_running = true;
JimCarver 0:6b753f761943 330
JimCarver 0:6b753f761943 331 // while events are being generated keep executing states
JimCarver 0:6b753f761943 332 while (_event_generated) {
JimCarver 0:6b753f761943 333 _event_generated = false; // event used up, reset flag
JimCarver 0:6b753f761943 334
JimCarver 0:6b753f761943 335 state_function(_current_state);
JimCarver 0:6b753f761943 336 }
JimCarver 0:6b753f761943 337
JimCarver 0:6b753f761943 338 _state_engine_running = false;
JimCarver 0:6b753f761943 339 }
JimCarver 0:6b753f761943 340
JimCarver 0:6b753f761943 341 void ConnectorClient::state_function(StartupSubStateRegistration current_state)
JimCarver 0:6b753f761943 342 {
JimCarver 0:6b753f761943 343 switch (current_state) {
JimCarver 0:6b753f761943 344 case State_Bootstrap_Start:
JimCarver 0:6b753f761943 345 state_bootstrap_start();
JimCarver 0:6b753f761943 346 break;
JimCarver 0:6b753f761943 347 case State_Bootstrap_Started:
JimCarver 0:6b753f761943 348 state_bootstrap_started();
JimCarver 0:6b753f761943 349 break;
JimCarver 0:6b753f761943 350 case State_Bootstrap_Success:
JimCarver 0:6b753f761943 351 state_bootstrap_success();
JimCarver 0:6b753f761943 352 break;
JimCarver 0:6b753f761943 353 case State_Bootstrap_Failure:
JimCarver 0:6b753f761943 354 state_bootstrap_failure();
JimCarver 0:6b753f761943 355 break;
JimCarver 0:6b753f761943 356 #ifndef MBED_CLIENT_DISABLE_EST_FEATURE
JimCarver 0:6b753f761943 357 case State_EST_Start:
JimCarver 0:6b753f761943 358 state_est_start();
JimCarver 0:6b753f761943 359 break;
JimCarver 0:6b753f761943 360 case State_EST_Started:
JimCarver 0:6b753f761943 361 state_est_started();
JimCarver 0:6b753f761943 362 break;
JimCarver 0:6b753f761943 363 case State_EST_Success:
JimCarver 0:6b753f761943 364 state_est_success();
JimCarver 0:6b753f761943 365 break;
JimCarver 0:6b753f761943 366 case State_EST_Failure:
JimCarver 0:6b753f761943 367 state_est_failure();
JimCarver 0:6b753f761943 368 break;
JimCarver 0:6b753f761943 369 #endif // !MBED_CLIENT_DISABLE_EST_FEATURE
JimCarver 0:6b753f761943 370 case State_Registration_Start:
JimCarver 0:6b753f761943 371 state_registration_start();
JimCarver 0:6b753f761943 372 break;
JimCarver 0:6b753f761943 373 case State_Registration_Started:
JimCarver 0:6b753f761943 374 state_registration_started();
JimCarver 0:6b753f761943 375 break;
JimCarver 0:6b753f761943 376 case State_Registration_Success:
JimCarver 0:6b753f761943 377 state_registration_success();
JimCarver 0:6b753f761943 378 break;
JimCarver 0:6b753f761943 379 case State_Registration_Failure:
JimCarver 0:6b753f761943 380 state_registration_failure();
JimCarver 0:6b753f761943 381 break;
JimCarver 0:6b753f761943 382 case State_Unregistered:
JimCarver 0:6b753f761943 383 state_unregistered();
JimCarver 0:6b753f761943 384 break;
JimCarver 0:6b753f761943 385 default:
JimCarver 0:6b753f761943 386 break;
JimCarver 0:6b753f761943 387 }
JimCarver 0:6b753f761943 388 }
JimCarver 0:6b753f761943 389
JimCarver 0:6b753f761943 390 /*
JimCarver 0:6b753f761943 391 * Creates register server object with mbed device server address and other parameters
JimCarver 0:6b753f761943 392 * required for client to connect to mbed device server.
JimCarver 0:6b753f761943 393 */
JimCarver 0:6b753f761943 394 void ConnectorClient::create_register_object()
JimCarver 0:6b753f761943 395 {
JimCarver 0:6b753f761943 396 tr_debug("ConnectorClient::create_register_object()");
JimCarver 0:6b753f761943 397 int32_t m2m_id = _security->get_security_instance_id(M2MSecurity::M2MServer);
JimCarver 0:6b753f761943 398 if (m2m_id == -1) {
JimCarver 0:6b753f761943 399 init_security_object();
JimCarver 0:6b753f761943 400 }
JimCarver 0:6b753f761943 401
JimCarver 0:6b753f761943 402 m2m_id = _security->get_security_instance_id(M2MSecurity::M2MServer);
JimCarver 0:6b753f761943 403 _security->set_resource_value(M2MSecurity::BootstrapServer, M2MSecurity::M2MServer, m2m_id);
JimCarver 0:6b753f761943 404
JimCarver 0:6b753f761943 405 // Add ResourceID's and values to the security ObjectID/ObjectInstance
JimCarver 0:6b753f761943 406 _security->set_resource_value(M2MSecurity::SecurityMode, _endpoint_info.mode, m2m_id);
JimCarver 0:6b753f761943 407
JimCarver 0:6b753f761943 408 // Allocate scratch buffer, this will be used to copy parameters from storage to security object
JimCarver 0:6b753f761943 409 const int max_size = MAX_CERTIFICATE_SIZE;
JimCarver 0:6b753f761943 410 uint8_t *buffer = (uint8_t*)malloc(max_size);
JimCarver 0:6b753f761943 411 size_t real_size = 0;
JimCarver 0:6b753f761943 412 bool success = false;
JimCarver 0:6b753f761943 413
JimCarver 0:6b753f761943 414 if (buffer != NULL) {
JimCarver 0:6b753f761943 415 success = true;
JimCarver 0:6b753f761943 416 }
JimCarver 0:6b753f761943 417 else {
JimCarver 0:6b753f761943 418 tr_error("ConnectorClient::create_register_object - Temporary certificate buffer allocation failed!");
JimCarver 0:6b753f761943 419 }
JimCarver 0:6b753f761943 420
JimCarver 0:6b753f761943 421 // Endpoint
JimCarver 0:6b753f761943 422 if (success) {
JimCarver 0:6b753f761943 423 success = false;
JimCarver 0:6b753f761943 424 char device_id[64];
JimCarver 0:6b753f761943 425
JimCarver 0:6b753f761943 426 size_t cert_size = max_size;
JimCarver 0:6b753f761943 427 uint8_t certificate[MAX_CERTIFICATE_SIZE];
JimCarver 0:6b753f761943 428 uint8_t *certificate_ptr = (uint8_t*)&certificate;
JimCarver 0:6b753f761943 429
JimCarver 0:6b753f761943 430 // TODO! Update to use chain api
JimCarver 0:6b753f761943 431 _security->resource_value_buffer(M2MSecurity::PublicKey, certificate_ptr, m2m_id, &cert_size);
JimCarver 0:6b753f761943 432 real_size = cert_size;
JimCarver 0:6b753f761943 433 if (extract_field_from_certificate((uint8_t*)certificate, real_size, "CN", device_id)) {
JimCarver 0:6b753f761943 434 tr_info("ConnectorClient::create_register_object - CN - endpoint_name : %s", device_id);
JimCarver 0:6b753f761943 435 _endpoint_info.endpoint_name = String(device_id);
JimCarver 0:6b753f761943 436 success = true;
JimCarver 0:6b753f761943 437 } else {
JimCarver 0:6b753f761943 438 tr_error("KEY_ENDPOINT_NAME failed.");
JimCarver 0:6b753f761943 439 }
JimCarver 0:6b753f761943 440 }
JimCarver 0:6b753f761943 441
JimCarver 0:6b753f761943 442 // Connector URL
JimCarver 0:6b753f761943 443 if (success) {
JimCarver 0:6b753f761943 444 success = false;
JimCarver 0:6b753f761943 445 if (ccs_get_item(g_fcc_lwm2m_server_uri_name, buffer, max_size, &real_size, CCS_CONFIG_ITEM) == CCS_STATUS_SUCCESS) {
JimCarver 0:6b753f761943 446 tr_info("ConnectorClient::create_register_object - M2MServerUri %.*s", (int)real_size, buffer);
JimCarver 0:6b753f761943 447 success = true;
JimCarver 0:6b753f761943 448 _security->set_resource_value(M2MSecurity::M2MServerUri, buffer, (uint32_t)real_size, m2m_id);
JimCarver 0:6b753f761943 449 }
JimCarver 0:6b753f761943 450 else
JimCarver 0:6b753f761943 451 tr_error("KEY_CONNECTOR_URL failed.");
JimCarver 0:6b753f761943 452 }
JimCarver 0:6b753f761943 453
JimCarver 0:6b753f761943 454 // Try to get internal endpoint name
JimCarver 0:6b753f761943 455 if (success) {
JimCarver 0:6b753f761943 456 if (ccs_get_item(KEY_INTERNAL_ENDPOINT, buffer, max_size, &real_size, CCS_CONFIG_ITEM) == CCS_STATUS_SUCCESS) {
JimCarver 0:6b753f761943 457 _endpoint_info.internal_endpoint_name = String((const char*)buffer, real_size);
JimCarver 0:6b753f761943 458 tr_info("ConnectorClient::create_register_object - internal endpoint name : %s", _endpoint_info.internal_endpoint_name.c_str());
JimCarver 0:6b753f761943 459 }
JimCarver 0:6b753f761943 460 else {
JimCarver 0:6b753f761943 461 tr_debug("KEY_INTERNAL_ENDPOINT failed.");
JimCarver 0:6b753f761943 462 }
JimCarver 0:6b753f761943 463 }
JimCarver 0:6b753f761943 464
JimCarver 0:6b753f761943 465 // Account ID, not mandatory
JimCarver 0:6b753f761943 466 if (success) {
JimCarver 0:6b753f761943 467 if (ccs_get_item(KEY_ACCOUNT_ID, buffer, max_size, &real_size, CCS_CONFIG_ITEM) == CCS_STATUS_SUCCESS) {
JimCarver 0:6b753f761943 468 tr_info("ConnectorClient::create_register_object - AccountId %.*s", (int)real_size, buffer);
JimCarver 0:6b753f761943 469 _endpoint_info.account_id = String((const char*)buffer, real_size);
JimCarver 0:6b753f761943 470 }
JimCarver 0:6b753f761943 471 else
JimCarver 0:6b753f761943 472 tr_debug("KEY_ACCOUNT_ID failed.");
JimCarver 0:6b753f761943 473 }
JimCarver 0:6b753f761943 474
JimCarver 0:6b753f761943 475 free(buffer);
JimCarver 0:6b753f761943 476 if (!success) {
JimCarver 0:6b753f761943 477 tr_error("ConnectorClient::create_register_object - Failed to read credentials");
JimCarver 0:6b753f761943 478 _callback->connector_error((M2MInterface::Error)MbedCloudClient::ConnectorFailedToReadCredentials,CREDENTIAL_ERROR);
JimCarver 0:6b753f761943 479 // TODO: what to do with the m2mserver security instance
JimCarver 0:6b753f761943 480 }
JimCarver 0:6b753f761943 481 }
JimCarver 0:6b753f761943 482
JimCarver 0:6b753f761943 483 /*
JimCarver 0:6b753f761943 484 * Creates bootstrap server object with bootstrap server address and other parameters
JimCarver 0:6b753f761943 485 * required for connecting to mbed Cloud bootstrap server.
JimCarver 0:6b753f761943 486 */
JimCarver 0:6b753f761943 487 bool ConnectorClient::create_bootstrap_object()
JimCarver 0:6b753f761943 488 {
JimCarver 0:6b753f761943 489 tr_debug("ConnectorClient::create_bootstrap_object");
JimCarver 0:6b753f761943 490 bool success = false;
JimCarver 0:6b753f761943 491
JimCarver 0:6b753f761943 492 // Check if bootstrap credentials are already stored in KCM
JimCarver 0:6b753f761943 493 if (bootstrap_credentials_stored_in_kcm() && _security) {
JimCarver 0:6b753f761943 494 int32_t bs_id = _security->get_security_instance_id(M2MSecurity::Bootstrap);
JimCarver 0:6b753f761943 495 _security->set_resource_value(M2MSecurity::SecurityMode, M2MSecurity::Certificate, bs_id);
JimCarver 0:6b753f761943 496
JimCarver 0:6b753f761943 497 tr_info("ConnectorClient::create_bootstrap_object - bs_id = %" PRId32, bs_id);
JimCarver 0:6b753f761943 498 tr_info("ConnectorClient::create_bootstrap_object - use credentials from storage");
JimCarver 0:6b753f761943 499
JimCarver 0:6b753f761943 500 // Allocate scratch buffer, this will be used to copy parameters from storage to security object
JimCarver 0:6b753f761943 501 size_t real_size = 0;
JimCarver 0:6b753f761943 502 const int max_size = MAX_CERTIFICATE_SIZE;
JimCarver 0:6b753f761943 503 uint8_t *buffer = (uint8_t*)malloc(max_size);
JimCarver 0:6b753f761943 504 if (buffer != NULL) {
JimCarver 0:6b753f761943 505 success = true;
JimCarver 0:6b753f761943 506 }
JimCarver 0:6b753f761943 507 else {
JimCarver 0:6b753f761943 508 tr_error("ConnectorClient::create_bootstrap_object - Temporary certificate buffer allocation failed!");
JimCarver 0:6b753f761943 509 }
JimCarver 0:6b753f761943 510
JimCarver 0:6b753f761943 511 // Read internal endpoint name if it exists, we need to append
JimCarver 0:6b753f761943 512 // it to bootstrap uri if device already bootstrapped
JimCarver 0:6b753f761943 513 uint8_t *iep = NULL;
JimCarver 0:6b753f761943 514 if (success && ccs_get_string_item(KEY_INTERNAL_ENDPOINT, buffer, max_size, CCS_CONFIG_ITEM) == CCS_STATUS_SUCCESS) {
JimCarver 0:6b753f761943 515 iep = (uint8_t*)malloc(strlen((const char*)buffer) + strlen(INTERNAL_ENDPOINT_PARAM) + 1);
JimCarver 0:6b753f761943 516 if (iep != NULL) {
JimCarver 0:6b753f761943 517 strcpy((char*)iep, INTERNAL_ENDPOINT_PARAM);
JimCarver 0:6b753f761943 518 strcat((char*)iep, (const char*)buffer);
JimCarver 0:6b753f761943 519 tr_info("ConnectorClient::create_bootstrap_object - iep: %s", buffer);
JimCarver 0:6b753f761943 520 }
JimCarver 0:6b753f761943 521 //TODO: Should handle error if iep exists but allocation fails?
JimCarver 0:6b753f761943 522 }
JimCarver 0:6b753f761943 523
JimCarver 0:6b753f761943 524 // Bootstrap URI
JimCarver 0:6b753f761943 525 if (success) {
JimCarver 0:6b753f761943 526 success = false;
JimCarver 0:6b753f761943 527 if (ccs_get_string_item(g_fcc_bootstrap_server_uri_name, buffer, max_size, CCS_CONFIG_ITEM) == CCS_STATUS_SUCCESS) {
JimCarver 0:6b753f761943 528 success = true;
JimCarver 0:6b753f761943 529
JimCarver 0:6b753f761943 530 real_size = strlen((const char*)buffer);
JimCarver 0:6b753f761943 531 // Append iep if we 1. have it 2. it doesn't already exist in uri 3. it fits
JimCarver 0:6b753f761943 532 if (iep &&
JimCarver 0:6b753f761943 533 strstr((const char*)buffer, (const char*)iep) == NULL &&
JimCarver 0:6b753f761943 534 (real_size + strlen((const char*)iep) + 1) <= max_size) {
JimCarver 0:6b753f761943 535 strcat((char*)buffer, (const char*)iep);
JimCarver 0:6b753f761943 536 real_size += strlen((const char*)iep) + 1;
JimCarver 0:6b753f761943 537 }
JimCarver 0:6b753f761943 538
JimCarver 0:6b753f761943 539 tr_info("ConnectorClient::create_bootstrap_object - M2MServerUri %.*s", (int)real_size, buffer);
JimCarver 0:6b753f761943 540 _security->set_resource_value(M2MSecurity::M2MServerUri, buffer, real_size, bs_id);
JimCarver 0:6b753f761943 541 }
JimCarver 0:6b753f761943 542 }
JimCarver 0:6b753f761943 543
JimCarver 0:6b753f761943 544 free(iep);
JimCarver 0:6b753f761943 545
JimCarver 0:6b753f761943 546 // Endpoint
JimCarver 0:6b753f761943 547 if (success) {
JimCarver 0:6b753f761943 548 success = false;
JimCarver 0:6b753f761943 549 if (ccs_get_item(g_fcc_endpoint_parameter_name, buffer, max_size, &real_size, CCS_CONFIG_ITEM) == CCS_STATUS_SUCCESS) {
JimCarver 0:6b753f761943 550 success = true;
JimCarver 0:6b753f761943 551 _endpoint_info.endpoint_name = String((const char*)buffer, real_size);
JimCarver 0:6b753f761943 552 tr_info("ConnectorClient::create_bootstrap_object - Endpoint %s", _endpoint_info.endpoint_name.c_str());
JimCarver 0:6b753f761943 553 }
JimCarver 0:6b753f761943 554 }
JimCarver 0:6b753f761943 555
JimCarver 0:6b753f761943 556 // Account ID, not mandatory
JimCarver 0:6b753f761943 557 if (success) {
JimCarver 0:6b753f761943 558 if (ccs_get_item(KEY_ACCOUNT_ID, buffer, max_size, &real_size, CCS_CONFIG_ITEM) == CCS_STATUS_SUCCESS) {
JimCarver 0:6b753f761943 559 _endpoint_info.account_id = String((const char*)buffer, real_size);
JimCarver 0:6b753f761943 560 tr_info("ConnectorClient::create_bootstrap_object - AccountId %s", _endpoint_info.account_id.c_str());
JimCarver 0:6b753f761943 561 }
JimCarver 0:6b753f761943 562 }
JimCarver 0:6b753f761943 563
JimCarver 0:6b753f761943 564 free(buffer);
JimCarver 0:6b753f761943 565
JimCarver 0:6b753f761943 566 if (!success) {
JimCarver 0:6b753f761943 567 tr_error("ConnectorClient::create_bootstrap_object - Failed to read credentials");
JimCarver 0:6b753f761943 568 _callback->connector_error((M2MInterface::Error)MbedCloudClient::ConnectorFailedToReadCredentials,CREDENTIAL_ERROR);
JimCarver 0:6b753f761943 569 _security->remove_object_instance(bs_id);
JimCarver 0:6b753f761943 570 }
JimCarver 0:6b753f761943 571 } else {
JimCarver 0:6b753f761943 572 success = true;
JimCarver 0:6b753f761943 573 tr_info("ConnectorClient::create_bootstrap_object - bootstrap object already done");
JimCarver 0:6b753f761943 574 }
JimCarver 0:6b753f761943 575
JimCarver 0:6b753f761943 576
JimCarver 0:6b753f761943 577 return success;
JimCarver 0:6b753f761943 578 }
JimCarver 0:6b753f761943 579
JimCarver 0:6b753f761943 580 void ConnectorClient::state_bootstrap_start()
JimCarver 0:6b753f761943 581 {
JimCarver 0:6b753f761943 582 tr_info("ConnectorClient::state_bootstrap_start()");
JimCarver 0:6b753f761943 583 assert(_interface != NULL);
JimCarver 0:6b753f761943 584 assert(_security != NULL);
JimCarver 0:6b753f761943 585
JimCarver 0:6b753f761943 586 _interface->bootstrap(_security);
JimCarver 0:6b753f761943 587
JimCarver 0:6b753f761943 588 internal_event(State_Bootstrap_Started);
JimCarver 0:6b753f761943 589 }
JimCarver 0:6b753f761943 590
JimCarver 0:6b753f761943 591 void ConnectorClient::state_bootstrap_started()
JimCarver 0:6b753f761943 592 {
JimCarver 0:6b753f761943 593 // this state may be useful only for verifying the callbacks?
JimCarver 0:6b753f761943 594 }
JimCarver 0:6b753f761943 595
JimCarver 0:6b753f761943 596 void ConnectorClient::state_bootstrap_success()
JimCarver 0:6b753f761943 597 {
JimCarver 0:6b753f761943 598 assert(_callback != NULL);
JimCarver 0:6b753f761943 599 // Parse internal endpoint name from mDS cert
JimCarver 0:6b753f761943 600 _callback->registration_process_result(State_Bootstrap_Success);
JimCarver 0:6b753f761943 601 }
JimCarver 0:6b753f761943 602
JimCarver 0:6b753f761943 603 void ConnectorClient::state_bootstrap_failure()
JimCarver 0:6b753f761943 604 {
JimCarver 0:6b753f761943 605 assert(_callback != NULL);
JimCarver 0:6b753f761943 606 // maybe some additional canceling and/or leanup is needed here?
JimCarver 0:6b753f761943 607 _callback->registration_process_result(State_Bootstrap_Failure);
JimCarver 0:6b753f761943 608 }
JimCarver 0:6b753f761943 609
JimCarver 0:6b753f761943 610 #ifndef MBED_CLIENT_DISABLE_EST_FEATURE
JimCarver 0:6b753f761943 611 void ConnectorClient::state_est_start()
JimCarver 0:6b753f761943 612 {
JimCarver 0:6b753f761943 613 // - Generate CSR from data during bootstrap phase
JimCarver 0:6b753f761943 614 // - Call EST enrollment API from InterfaceImpl
JimCarver 0:6b753f761943 615
JimCarver 0:6b753f761943 616 // Update the internal endpoint name and account id to endpoint info structure
JimCarver 0:6b753f761943 617 // as we get those during bootstrap phase
JimCarver 0:6b753f761943 618 _endpoint_info.internal_endpoint_name = _interface->internal_endpoint_name();
JimCarver 0:6b753f761943 619
JimCarver 0:6b753f761943 620 int32_t m2m_id = _security->get_security_instance_id(M2MSecurity::M2MServer);
JimCarver 0:6b753f761943 621 uint32_t sec_mode = M2MSecurity::SecurityNotSet;
JimCarver 0:6b753f761943 622 if (m2m_id >= 0) {
JimCarver 0:6b753f761943 623 sec_mode = _security->resource_value_int(M2MSecurity::SecurityMode, m2m_id);
JimCarver 0:6b753f761943 624
JimCarver 0:6b753f761943 625 // We need to parse account id from lwm2m server uri query if it is not yet
JimCarver 0:6b753f761943 626 // set in endpoint info structure
JimCarver 0:6b753f761943 627 if (_endpoint_info.account_id.length() <= 0) {
JimCarver 0:6b753f761943 628 String address = _security->resource_value_string(M2MSecurity::M2MServerUri, m2m_id);
JimCarver 0:6b753f761943 629 tr_debug("ConnectorClient::state_est_start - address: %s", address.c_str());
JimCarver 0:6b753f761943 630 if (address.size() > 0) {
JimCarver 0:6b753f761943 631 const char *aid = NULL;
JimCarver 0:6b753f761943 632 const int aid_size = parse_query_parameter_value_from_uri((const char*)address.c_str(), QUERY_PARAM_AID, &aid);
JimCarver 0:6b753f761943 633 if (aid_size > 0) {
JimCarver 0:6b753f761943 634 _endpoint_info.account_id.append_raw(aid, aid_size);
JimCarver 0:6b753f761943 635 }
JimCarver 0:6b753f761943 636 }
JimCarver 0:6b753f761943 637 }
JimCarver 0:6b753f761943 638 }
JimCarver 0:6b753f761943 639
JimCarver 0:6b753f761943 640 tr_debug("ConnectorClient::state_est_start - security instance id: %" PRId32, m2m_id);
JimCarver 0:6b753f761943 641 tr_debug("ConnectorClient::state_est_start - ep: %s", _endpoint_info.internal_endpoint_name.c_str());
JimCarver 0:6b753f761943 642 tr_debug("ConnectorClient::state_est_start - iep: %s", _endpoint_info.endpoint_name.c_str());
JimCarver 0:6b753f761943 643 tr_debug("ConnectorClient::state_est_start - aid: %s", _endpoint_info.account_id.c_str());
JimCarver 0:6b753f761943 644
JimCarver 0:6b753f761943 645 // Check EST required parameters are in place
JimCarver 0:6b753f761943 646 if (m2m_id < 0 ||
JimCarver 0:6b753f761943 647 _endpoint_info.endpoint_name.length() <= 0 ||
JimCarver 0:6b753f761943 648 _endpoint_info.internal_endpoint_name.length() <= 0 ||
JimCarver 0:6b753f761943 649 _endpoint_info.account_id.length() <= 0) {
JimCarver 0:6b753f761943 650 tr_error("ConnectorClient::state_est_start - Missing parameters for EST enrollment!");
JimCarver 0:6b753f761943 651 internal_event(State_EST_Failure);
JimCarver 0:6b753f761943 652 return;
JimCarver 0:6b753f761943 653 }
JimCarver 0:6b753f761943 654
JimCarver 0:6b753f761943 655 uint32_t is_bs_server = _security->resource_value_int(M2MSecurity::BootstrapServer, m2m_id);
JimCarver 0:6b753f761943 656 size_t public_key_size = MAX_CERTIFICATE_SIZE;
JimCarver 0:6b753f761943 657 size_t server_key_size = MAX_CERTIFICATE_SIZE;
JimCarver 0:6b753f761943 658 size_t private_key_size = MAX_CERTIFICATE_SIZE;
JimCarver 0:6b753f761943 659
JimCarver 0:6b753f761943 660 // Temp buffer for storing CSR and certificates
JimCarver 0:6b753f761943 661 uint8_t *buffer = (uint8_t*)malloc(MAX_CERTIFICATE_SIZE);
JimCarver 0:6b753f761943 662 size_t real_size = 0;
JimCarver 0:6b753f761943 663 if (buffer == NULL) {
JimCarver 0:6b753f761943 664 tr_error("ConnectorClient::state_est_start - Allocating temp buffer failed!");
JimCarver 0:6b753f761943 665 internal_event(State_EST_Failure);
JimCarver 0:6b753f761943 666 return;
JimCarver 0:6b753f761943 667 }
JimCarver 0:6b753f761943 668 uint8_t *buffer_ptr = buffer;
JimCarver 0:6b753f761943 669
JimCarver 0:6b753f761943 670 // TODO! Update to use chain api
JimCarver 0:6b753f761943 671 if (_security->resource_value_buffer(M2MSecurity::PublicKey, buffer_ptr, m2m_id, &public_key_size) != 0) {
JimCarver 0:6b753f761943 672 public_key_size = 0;
JimCarver 0:6b753f761943 673 }
JimCarver 0:6b753f761943 674 if (_security->resource_value_buffer(M2MSecurity::ServerPublicKey, buffer_ptr, m2m_id, &server_key_size) != 0) {
JimCarver 0:6b753f761943 675 server_key_size = 0;
JimCarver 0:6b753f761943 676 }
JimCarver 0:6b753f761943 677 if (_security->resource_value_buffer(M2MSecurity::Secretkey, buffer_ptr, m2m_id, &private_key_size) != 0) {
JimCarver 0:6b753f761943 678 private_key_size = 0;
JimCarver 0:6b753f761943 679 }
JimCarver 0:6b753f761943 680
JimCarver 0:6b753f761943 681 tr_info("est check - is bs server /0/1: %" PRIu32, is_bs_server);
JimCarver 0:6b753f761943 682 tr_info("est check - Security Mode /0/2: %" PRIu32, sec_mode);
JimCarver 0:6b753f761943 683 tr_info("est check - Public key size /0/3: %" PRIu32, public_key_size);
JimCarver 0:6b753f761943 684 tr_info("est check - Server Public key size /0/4: %" PRIu32, server_key_size);
JimCarver 0:6b753f761943 685 tr_info("est check - Secret key size /0/5: %" PRIu32, private_key_size);
JimCarver 0:6b753f761943 686
JimCarver 0:6b753f761943 687 // Configure CSR params
JimCarver 0:6b753f761943 688 kcm_csr_params_s csr_params;
JimCarver 0:6b753f761943 689 int subject_size = snprintf(NULL, 0, LWM2M_CSR_SUBJECT_FORMAT,
JimCarver 0:6b753f761943 690 _endpoint_info.internal_endpoint_name.c_str(),
JimCarver 0:6b753f761943 691 _endpoint_info.account_id.c_str(),
JimCarver 0:6b753f761943 692 _endpoint_info.endpoint_name.c_str());
JimCarver 0:6b753f761943 693 if (subject_size <= 0) {
JimCarver 0:6b753f761943 694 tr_error("ConnectorClient::state_est_start - CSR Subject formatting failed!");
JimCarver 0:6b753f761943 695 free(buffer);
JimCarver 0:6b753f761943 696 internal_event(State_EST_Failure);
JimCarver 0:6b753f761943 697 return;
JimCarver 0:6b753f761943 698 }
JimCarver 0:6b753f761943 699
JimCarver 0:6b753f761943 700 // For null-terminator
JimCarver 0:6b753f761943 701 subject_size++;
JimCarver 0:6b753f761943 702
JimCarver 0:6b753f761943 703 csr_params.subject = (char*)malloc(subject_size);
JimCarver 0:6b753f761943 704 if (csr_params.subject == NULL) {
JimCarver 0:6b753f761943 705 tr_error("ConnectorClient::state_est_start - CSR Subject formatting failed!");
JimCarver 0:6b753f761943 706 free(buffer);
JimCarver 0:6b753f761943 707 internal_event(State_EST_Failure);
JimCarver 0:6b753f761943 708 return;
JimCarver 0:6b753f761943 709 }
JimCarver 0:6b753f761943 710
JimCarver 0:6b753f761943 711 snprintf(csr_params.subject, subject_size, LWM2M_CSR_SUBJECT_FORMAT,
JimCarver 0:6b753f761943 712 _endpoint_info.internal_endpoint_name.c_str(),
JimCarver 0:6b753f761943 713 _endpoint_info.account_id.c_str(),
JimCarver 0:6b753f761943 714 _endpoint_info.endpoint_name.c_str());
JimCarver 0:6b753f761943 715
JimCarver 0:6b753f761943 716 tr_debug("est csr subject '%s'", csr_params.subject);
JimCarver 0:6b753f761943 717
JimCarver 0:6b753f761943 718 csr_params.md_type = KCM_MD_SHA256;
JimCarver 0:6b753f761943 719 csr_params.key_usage = KCM_CSR_KU_NONE;
JimCarver 0:6b753f761943 720 csr_params.ext_key_usage = KCM_CSR_EXT_KU_NONE;
JimCarver 0:6b753f761943 721
JimCarver 0:6b753f761943 722 kcm_status_e status = kcm_generate_keys_and_csr(KCM_SCHEME_EC_SECP256R1,
JimCarver 0:6b753f761943 723 (const uint8_t*)g_fcc_lwm2m_device_private_key_name,
JimCarver 0:6b753f761943 724 strlen(g_fcc_lwm2m_device_private_key_name),
JimCarver 0:6b753f761943 725 NULL,
JimCarver 0:6b753f761943 726 0,
JimCarver 0:6b753f761943 727 false,
JimCarver 0:6b753f761943 728 &csr_params,
JimCarver 0:6b753f761943 729 buffer,
JimCarver 0:6b753f761943 730 MAX_CERTIFICATE_SIZE,
JimCarver 0:6b753f761943 731 &real_size,
JimCarver 0:6b753f761943 732 NULL);
JimCarver 0:6b753f761943 733
JimCarver 0:6b753f761943 734 free(csr_params.subject);
JimCarver 0:6b753f761943 735
JimCarver 0:6b753f761943 736 if (status != KCM_STATUS_SUCCESS) {
JimCarver 0:6b753f761943 737 tr_error("ConnectorClient::state_est_start - Generating keys and csr failed!");
JimCarver 0:6b753f761943 738 free(buffer);
JimCarver 0:6b753f761943 739 internal_event(State_EST_Failure);
JimCarver 0:6b753f761943 740 return;
JimCarver 0:6b753f761943 741 }
JimCarver 0:6b753f761943 742
JimCarver 0:6b753f761943 743 // Update state and start the enrollment by sending the enroll request
JimCarver 0:6b753f761943 744 internal_event(State_EST_Started);
JimCarver 0:6b753f761943 745 _interface->post_data_request("est/sen",
JimCarver 0:6b753f761943 746 false,
JimCarver 0:6b753f761943 747 real_size,
JimCarver 0:6b753f761943 748 buffer,
JimCarver 0:6b753f761943 749 ConnectorClient::est_post_data_cb,
JimCarver 0:6b753f761943 750 ConnectorClient::est_post_data_error_cb,
JimCarver 0:6b753f761943 751 this);
JimCarver 0:6b753f761943 752
JimCarver 0:6b753f761943 753 free(buffer);
JimCarver 0:6b753f761943 754 }
JimCarver 0:6b753f761943 755
JimCarver 0:6b753f761943 756 void ConnectorClient::state_est_started()
JimCarver 0:6b753f761943 757 {
JimCarver 0:6b753f761943 758 }
JimCarver 0:6b753f761943 759
JimCarver 0:6b753f761943 760 void ConnectorClient::state_est_success()
JimCarver 0:6b753f761943 761 {
JimCarver 0:6b753f761943 762 tr_info("ConnectorClient::state_est_success()");
JimCarver 0:6b753f761943 763 _interface->finish_bootstrap();
JimCarver 0:6b753f761943 764 }
JimCarver 0:6b753f761943 765
JimCarver 0:6b753f761943 766 void ConnectorClient::state_est_failure()
JimCarver 0:6b753f761943 767 {
JimCarver 0:6b753f761943 768 tr_info("ConnectorClient::state_est_failure()");
JimCarver 0:6b753f761943 769 internal_event(State_Bootstrap_Failure);
JimCarver 0:6b753f761943 770 //Failed to store credentials, bootstrap failed
JimCarver 0:6b753f761943 771 _callback->connector_error(M2MInterface::ESTEnrollmentFailed, ERROR_EST_ENROLLMENT_REQUEST_FAILED); // Translated to error code ConnectMemoryConnectFail
JimCarver 0:6b753f761943 772 }
JimCarver 0:6b753f761943 773 #endif /* !MBED_CLIENT_DISABLE_EST_FEATURE */
JimCarver 0:6b753f761943 774
JimCarver 0:6b753f761943 775 void ConnectorClient::state_registration_start()
JimCarver 0:6b753f761943 776 {
JimCarver 0:6b753f761943 777 tr_info("ConnectorClient::state_registration_start()");
JimCarver 0:6b753f761943 778 assert(_interface != NULL);
JimCarver 0:6b753f761943 779 assert(_security != NULL);
JimCarver 0:6b753f761943 780 _interface->register_object(_security, *_client_objs);
JimCarver 0:6b753f761943 781 internal_event(State_Registration_Started);
JimCarver 0:6b753f761943 782 }
JimCarver 0:6b753f761943 783
JimCarver 0:6b753f761943 784 void ConnectorClient::state_registration_started()
JimCarver 0:6b753f761943 785 {
JimCarver 0:6b753f761943 786 // this state may be useful only for verifying the callbacks?
JimCarver 0:6b753f761943 787 }
JimCarver 0:6b753f761943 788
JimCarver 0:6b753f761943 789 void ConnectorClient::state_registration_success()
JimCarver 0:6b753f761943 790 {
JimCarver 0:6b753f761943 791 assert(_callback != NULL);
JimCarver 0:6b753f761943 792 _endpoint_info.internal_endpoint_name = _interface->internal_endpoint_name();
JimCarver 0:6b753f761943 793
JimCarver 0:6b753f761943 794 //The endpoint is maximum 32 character long, we put bigger buffer for future extensions
JimCarver 0:6b753f761943 795 const int max_size = 64;
JimCarver 0:6b753f761943 796 uint8_t buffer[max_size];
JimCarver 0:6b753f761943 797
JimCarver 0:6b753f761943 798 bool no_param_update = true;
JimCarver 0:6b753f761943 799
JimCarver 0:6b753f761943 800 if(ccs_get_string_item(KEY_INTERNAL_ENDPOINT, buffer, max_size, CCS_CONFIG_ITEM) == CCS_STATUS_SUCCESS) {
JimCarver 0:6b753f761943 801 if (strcmp((const char*)buffer, _endpoint_info.internal_endpoint_name.c_str()) != 0) {
JimCarver 0:6b753f761943 802 // Update is required as the stored KCM entry is different than _endpoint_info.internal_endpoint_name.
JimCarver 0:6b753f761943 803 no_param_update = false;
JimCarver 0:6b753f761943 804 }
JimCarver 0:6b753f761943 805 }
JimCarver 0:6b753f761943 806
JimCarver 0:6b753f761943 807 // Update INTERNAL_ENDPOINT setting only if there is no such entry or the value is not matching the
JimCarver 0:6b753f761943 808 // _endpoint_info.internal_endpoint_name.
JimCarver 0:6b753f761943 809 if(!no_param_update) {
JimCarver 0:6b753f761943 810 ccs_delete_item(KEY_INTERNAL_ENDPOINT, CCS_CONFIG_ITEM);
JimCarver 0:6b753f761943 811 ccs_set_item(KEY_INTERNAL_ENDPOINT, (const uint8_t*)_endpoint_info.internal_endpoint_name.c_str(),
JimCarver 0:6b753f761943 812 (size_t)_endpoint_info.internal_endpoint_name.size(),
JimCarver 0:6b753f761943 813 CCS_CONFIG_ITEM);
JimCarver 0:6b753f761943 814 }
JimCarver 0:6b753f761943 815
JimCarver 0:6b753f761943 816 _callback->registration_process_result(State_Registration_Success);
JimCarver 0:6b753f761943 817 }
JimCarver 0:6b753f761943 818
JimCarver 0:6b753f761943 819 void ConnectorClient::state_registration_failure()
JimCarver 0:6b753f761943 820 {
JimCarver 0:6b753f761943 821 assert(_callback != NULL);
JimCarver 0:6b753f761943 822 // maybe some additional canceling and/or leanup is needed here?
JimCarver 0:6b753f761943 823 _callback->registration_process_result(State_Registration_Failure);
JimCarver 0:6b753f761943 824 }
JimCarver 0:6b753f761943 825
JimCarver 0:6b753f761943 826 void ConnectorClient::state_unregistered()
JimCarver 0:6b753f761943 827 {
JimCarver 0:6b753f761943 828 assert(_callback != NULL);
JimCarver 0:6b753f761943 829 _callback->registration_process_result(State_Unregistered);
JimCarver 0:6b753f761943 830 }
JimCarver 0:6b753f761943 831
JimCarver 0:6b753f761943 832 void ConnectorClient::bootstrap_data_ready(M2MSecurity *security_object)
JimCarver 0:6b753f761943 833 {
JimCarver 0:6b753f761943 834 tr_info("ConnectorClient::bootstrap_data_ready");
JimCarver 0:6b753f761943 835 ccs_status_e status = CCS_STATUS_ERROR;
JimCarver 0:6b753f761943 836 if(security_object) {
JimCarver 0:6b753f761943 837 // Update bootstrap credentials (we could skip this if we knew whether they were updated)
JimCarver 0:6b753f761943 838 // This will also update the address in case of first to claim
JimCarver 0:6b753f761943 839 status = set_bootstrap_credentials(security_object);
JimCarver 0:6b753f761943 840 if (status != CCS_STATUS_SUCCESS) {
JimCarver 0:6b753f761943 841 // TODO: what now?
JimCarver 0:6b753f761943 842 tr_error("ConnectorClient::bootstrap_data_ready - couldn't store bootstrap credentials");
JimCarver 0:6b753f761943 843 }
JimCarver 0:6b753f761943 844
JimCarver 0:6b753f761943 845 // Clear the first to claim flag if it's active
JimCarver 0:6b753f761943 846 if (is_first_to_claim()) {
JimCarver 0:6b753f761943 847 status = clear_first_to_claim();
JimCarver 0:6b753f761943 848 if (status != CCS_STATUS_SUCCESS) {
JimCarver 0:6b753f761943 849 // TODO: what now?
JimCarver 0:6b753f761943 850 tr_error("ConnectorClient::bootstrap_data_ready - couldn't clear first to claim flag!");
JimCarver 0:6b753f761943 851 }
JimCarver 0:6b753f761943 852 }
JimCarver 0:6b753f761943 853
JimCarver 0:6b753f761943 854 // Bootstrap might delete m2mserver security object instance completely to force bootstrap
JimCarver 0:6b753f761943 855 // with new credentials, in that case delete the stored lwm2m credentials as well and re-bootstrap
JimCarver 0:6b753f761943 856 if (security_object->get_security_instance_id(M2MSecurity::M2MServer) == -1) {
JimCarver 0:6b753f761943 857 tr_info("ConnectorClient::bootstrap_data_ready() - Clearing lwm2m credentials");
JimCarver 0:6b753f761943 858 // delete the old connector credentials when BS sends re-direction.
JimCarver 0:6b753f761943 859 ccs_delete_item(g_fcc_lwm2m_server_uri_name, CCS_CONFIG_ITEM);
JimCarver 0:6b753f761943 860 ccs_delete_item(g_fcc_lwm2m_server_ca_certificate_name, CCS_CERTIFICATE_ITEM);
JimCarver 0:6b753f761943 861 ccs_delete_item(g_fcc_lwm2m_device_certificate_name, CCS_CERTIFICATE_ITEM);
JimCarver 0:6b753f761943 862 ccs_delete_item(g_fcc_lwm2m_device_private_key_name, CCS_PRIVATE_KEY_ITEM);
JimCarver 0:6b753f761943 863 // Start re-bootstrap timer
JimCarver 0:6b753f761943 864 tr_info("ConnectorClient::bootstrap_data_ready() - Re-directing bootstrap in 100 milliseconds");
JimCarver 0:6b753f761943 865 _rebootstrap_timer.start_timer(100, M2MTimerObserver::BootstrapFlowTimer, true);
JimCarver 0:6b753f761943 866 return;
JimCarver 0:6b753f761943 867 }
JimCarver 0:6b753f761943 868 // Bootstrap wrote M2MServer credentials, store them and also update first to claim status if it's configured
JimCarver 0:6b753f761943 869 else {
JimCarver 0:6b753f761943 870 #ifndef MBED_CLIENT_DISABLE_EST_FEATURE
JimCarver 0:6b753f761943 871 int32_t m2m_id = _security->get_security_instance_id(M2MSecurity::M2MServer);
JimCarver 0:6b753f761943 872 if (m2m_id >= 0 &&
JimCarver 0:6b753f761943 873 _security->resource_value_int(M2MSecurity::SecurityMode, m2m_id) == M2MSecurity::EST) {
JimCarver 0:6b753f761943 874 // If EST is supported, continue to EST state to start EST enrollment
JimCarver 0:6b753f761943 875 tr_info("ConnectorClient::bootstrap_data_ready() - Continue to EST enrollment");
JimCarver 0:6b753f761943 876 internal_event(State_EST_Start);
JimCarver 0:6b753f761943 877 return;
JimCarver 0:6b753f761943 878 }
JimCarver 0:6b753f761943 879 #endif // MBED_CLIENT_DISABLE_EST_FEATURE
JimCarver 0:6b753f761943 880 // Security mode was not EST, in that case just store the received credentials
JimCarver 0:6b753f761943 881 tr_info("ConnectorClient::bootstrap_data_ready() - Storing lwm2m credentials");
JimCarver 0:6b753f761943 882 status = set_connector_credentials(security_object);
JimCarver 0:6b753f761943 883 }
JimCarver 0:6b753f761943 884
JimCarver 0:6b753f761943 885 if (status != CCS_STATUS_SUCCESS) {
JimCarver 0:6b753f761943 886 internal_event(State_Bootstrap_Failure);
JimCarver 0:6b753f761943 887 //Failed to store credentials, bootstrap failed
JimCarver 0:6b753f761943 888 _callback->connector_error(M2MInterface::MemoryFail, ERROR_NO_MEMORY); // Translated to error code ConnectMemoryConnectFail
JimCarver 0:6b753f761943 889 return;
JimCarver 0:6b753f761943 890 } else {
JimCarver 0:6b753f761943 891 tr_info("ConnectorClient::bootstrap_data_ready - set_credentials status %d", status);
JimCarver 0:6b753f761943 892 }
JimCarver 0:6b753f761943 893 }
JimCarver 0:6b753f761943 894 }
JimCarver 0:6b753f761943 895
JimCarver 0:6b753f761943 896 void ConnectorClient::bootstrap_done(M2MSecurity *security_object)
JimCarver 0:6b753f761943 897 {
JimCarver 0:6b753f761943 898 tr_info("ConnectorClient::bootstrap_done");
JimCarver 0:6b753f761943 899 internal_event(State_Bootstrap_Success);
JimCarver 0:6b753f761943 900 }
JimCarver 0:6b753f761943 901
JimCarver 0:6b753f761943 902 void ConnectorClient::object_registered(M2MSecurity *security_object, const M2MServer &server_object)
JimCarver 0:6b753f761943 903 {
JimCarver 0:6b753f761943 904 internal_event(State_Registration_Success);
JimCarver 0:6b753f761943 905 }
JimCarver 0:6b753f761943 906
JimCarver 0:6b753f761943 907 void ConnectorClient::object_unregistered(M2MSecurity *server_object)
JimCarver 0:6b753f761943 908 {
JimCarver 0:6b753f761943 909 internal_event(State_Unregistered);
JimCarver 0:6b753f761943 910 }
JimCarver 0:6b753f761943 911
JimCarver 0:6b753f761943 912 void ConnectorClient::registration_updated(M2MSecurity *security_object, const M2MServer & server_object)
JimCarver 0:6b753f761943 913 {
JimCarver 0:6b753f761943 914 _callback->registration_process_result(State_Registration_Updated);
JimCarver 0:6b753f761943 915 }
JimCarver 0:6b753f761943 916
JimCarver 0:6b753f761943 917 void ConnectorClient::error(M2MInterface::Error error)
JimCarver 0:6b753f761943 918 {
JimCarver 0:6b753f761943 919 tr_error("ConnectorClient::error() - error: %d", error);
JimCarver 0:6b753f761943 920 assert(_callback != NULL);
JimCarver 0:6b753f761943 921 if (_current_state >= State_Registration_Start &&
JimCarver 0:6b753f761943 922 use_bootstrap() &&
JimCarver 0:6b753f761943 923 (error == M2MInterface::SecureConnectionFailed ||
JimCarver 0:6b753f761943 924 error == M2MInterface::InvalidParameters)) {
JimCarver 0:6b753f761943 925 tr_info("ConnectorClient::error() - Error during lwm2m registration");
JimCarver 0:6b753f761943 926 tr_info("ConnectorClient::error() - Clearing lwm2m credentials");
JimCarver 0:6b753f761943 927 // delete the old connector credentials when DTLS handshake fails or
JimCarver 0:6b753f761943 928 // server rejects the registration.
JimCarver 0:6b753f761943 929 ccs_delete_item(g_fcc_lwm2m_server_uri_name, CCS_CONFIG_ITEM);
JimCarver 0:6b753f761943 930 ccs_delete_item(g_fcc_lwm2m_server_ca_certificate_name, CCS_CERTIFICATE_ITEM);
JimCarver 0:6b753f761943 931 ccs_delete_item(g_fcc_lwm2m_device_certificate_name, CCS_CERTIFICATE_ITEM);
JimCarver 0:6b753f761943 932 ccs_delete_item(g_fcc_lwm2m_device_private_key_name, CCS_PRIVATE_KEY_ITEM);
JimCarver 0:6b753f761943 933 // Delete the lwm2m security instance
JimCarver 0:6b753f761943 934 int32_t id = _security->get_security_instance_id(M2MSecurity::M2MServer);
JimCarver 0:6b753f761943 935 if (id >= 0) {
JimCarver 0:6b753f761943 936 _security->remove_object_instance(id);
JimCarver 0:6b753f761943 937 }
JimCarver 0:6b753f761943 938 // Start re-bootstrap timer
JimCarver 0:6b753f761943 939 tr_info("ConnectorClient::error() - Re-bootstrapping in 100 milliseconds");
JimCarver 0:6b753f761943 940 _rebootstrap_timer.start_timer(100, M2MTimerObserver::BootstrapFlowTimer, true);
JimCarver 0:6b753f761943 941 }
JimCarver 0:6b753f761943 942 else {
JimCarver 0:6b753f761943 943 _callback->connector_error(error, _interface->error_description());
JimCarver 0:6b753f761943 944 }
JimCarver 0:6b753f761943 945 }
JimCarver 0:6b753f761943 946
JimCarver 0:6b753f761943 947 void ConnectorClient::value_updated(M2MBase *base, M2MBase::BaseType type)
JimCarver 0:6b753f761943 948 {
JimCarver 0:6b753f761943 949 assert(_callback != NULL);
JimCarver 0:6b753f761943 950 _callback->value_updated(base, type);
JimCarver 0:6b753f761943 951 }
JimCarver 0:6b753f761943 952
JimCarver 0:6b753f761943 953 bool ConnectorClient::connector_credentials_available()
JimCarver 0:6b753f761943 954 {
JimCarver 0:6b753f761943 955 tr_debug("ConnectorClient::connector_credentials_available");
JimCarver 0:6b753f761943 956 // Read 1 byte of lwm2m private key, should return real_size > 0 if it exists
JimCarver 0:6b753f761943 957 const int max_size = 1;
JimCarver 0:6b753f761943 958 uint8_t buffer;
JimCarver 0:6b753f761943 959 size_t real_size = 0;
JimCarver 0:6b753f761943 960 ccs_get_item(g_fcc_lwm2m_device_private_key_name, &buffer, max_size, &real_size, CCS_PRIVATE_KEY_ITEM);
JimCarver 0:6b753f761943 961 if (real_size > 0) {
JimCarver 0:6b753f761943 962 return true;
JimCarver 0:6b753f761943 963 }
JimCarver 0:6b753f761943 964 return false;
JimCarver 0:6b753f761943 965 }
JimCarver 0:6b753f761943 966
JimCarver 0:6b753f761943 967 bool ConnectorClient::use_bootstrap()
JimCarver 0:6b753f761943 968 {
JimCarver 0:6b753f761943 969 tr_debug("ConnectorClient::use_bootstrap");
JimCarver 0:6b753f761943 970 size_t real_size = 0;
JimCarver 0:6b753f761943 971 uint8_t data[CONFIG_BOOLEAN_ITEM_SIZE] = {0};
JimCarver 0:6b753f761943 972 uint32_t value = 0;
JimCarver 0:6b753f761943 973 ccs_status_e status = ccs_get_item(g_fcc_use_bootstrap_parameter_name, data, CONFIG_BOOLEAN_ITEM_SIZE, &real_size, CCS_CONFIG_ITEM);
JimCarver 0:6b753f761943 974 if (status == CCS_STATUS_SUCCESS) {
JimCarver 0:6b753f761943 975 memcpy(&value, data, CONFIG_BOOLEAN_ITEM_SIZE);
JimCarver 0:6b753f761943 976 // Return true if use_bootstrap is set
JimCarver 0:6b753f761943 977 if (value == 1) {
JimCarver 0:6b753f761943 978 return true;
JimCarver 0:6b753f761943 979 }
JimCarver 0:6b753f761943 980 }
JimCarver 0:6b753f761943 981 return false;
JimCarver 0:6b753f761943 982 }
JimCarver 0:6b753f761943 983
JimCarver 0:6b753f761943 984
JimCarver 0:6b753f761943 985 bool ConnectorClient::get_key(const char *key, const char *endpoint, char *&key_name)
JimCarver 0:6b753f761943 986 {
JimCarver 0:6b753f761943 987 if(key_name) {
JimCarver 0:6b753f761943 988 free(key_name);
JimCarver 0:6b753f761943 989 key_name = NULL;
JimCarver 0:6b753f761943 990 }
JimCarver 0:6b753f761943 991
JimCarver 0:6b753f761943 992 key_name = (char*)malloc(strlen(key)+strlen(endpoint)+1);
JimCarver 0:6b753f761943 993 if(key_name) {
JimCarver 0:6b753f761943 994 strcpy(key_name, key);
JimCarver 0:6b753f761943 995 strcat(key_name, endpoint);
JimCarver 0:6b753f761943 996 tr_debug("key %s", key_name);
JimCarver 0:6b753f761943 997 return true;
JimCarver 0:6b753f761943 998 }
JimCarver 0:6b753f761943 999 return false;
JimCarver 0:6b753f761943 1000 }
JimCarver 0:6b753f761943 1001
JimCarver 0:6b753f761943 1002 ccs_status_e ConnectorClient::set_connector_credentials(M2MSecurity *security)
JimCarver 0:6b753f761943 1003 {
JimCarver 0:6b753f761943 1004 tr_debug("ConnectorClient::set_connector_credentials");
JimCarver 0:6b753f761943 1005 ccs_status_e status = CCS_STATUS_ERROR;
JimCarver 0:6b753f761943 1006
JimCarver 0:6b753f761943 1007 int32_t m2m_id = security->get_security_instance_id(M2MSecurity::M2MServer);
JimCarver 0:6b753f761943 1008 if (m2m_id == -1) {
JimCarver 0:6b753f761943 1009 return status;
JimCarver 0:6b753f761943 1010 }
JimCarver 0:6b753f761943 1011
JimCarver 0:6b753f761943 1012 size_t buffer_size = MAX_CERTIFICATE_SIZE;
JimCarver 0:6b753f761943 1013 uint8_t public_key[MAX_CERTIFICATE_SIZE];
JimCarver 0:6b753f761943 1014 uint8_t *public_key_ptr = (uint8_t*)&public_key;
JimCarver 0:6b753f761943 1015
JimCarver 0:6b753f761943 1016 // TODO! Update to use chain api
JimCarver 0:6b753f761943 1017 if (security->resource_value_buffer(M2MSecurity::PublicKey, public_key_ptr, m2m_id, &buffer_size) != 0) {
JimCarver 0:6b753f761943 1018 return status;
JimCarver 0:6b753f761943 1019 }
JimCarver 0:6b753f761943 1020
JimCarver 0:6b753f761943 1021 char device_id[64];
JimCarver 0:6b753f761943 1022 memset(device_id, 0, 64);
JimCarver 0:6b753f761943 1023 if (extract_field_from_certificate(public_key, buffer_size, "L", device_id)) {
JimCarver 0:6b753f761943 1024 tr_info("ConnectorClient::set_connector_credentials - L internal_endpoint_name : %s", device_id);
JimCarver 0:6b753f761943 1025 _endpoint_info.internal_endpoint_name = String(device_id);
JimCarver 0:6b753f761943 1026 ccs_delete_item(KEY_INTERNAL_ENDPOINT, CCS_CONFIG_ITEM);
JimCarver 0:6b753f761943 1027 status = ccs_set_item(KEY_INTERNAL_ENDPOINT,(uint8_t*)device_id, strlen(device_id), CCS_CONFIG_ITEM);
JimCarver 0:6b753f761943 1028 }
JimCarver 0:6b753f761943 1029
JimCarver 0:6b753f761943 1030 memset(device_id, 0, 64);
JimCarver 0:6b753f761943 1031 if (extract_field_from_certificate(public_key, buffer_size, "CN", device_id)) {
JimCarver 0:6b753f761943 1032 tr_info("ConnectorClient::set_connector_credentials - CN endpoint_name : %s", device_id);
JimCarver 0:6b753f761943 1033 _endpoint_info.endpoint_name = String(device_id);
JimCarver 0:6b753f761943 1034 }
JimCarver 0:6b753f761943 1035
JimCarver 0:6b753f761943 1036 if(status == CCS_STATUS_SUCCESS) {
JimCarver 0:6b753f761943 1037 ccs_status_e check_status = ccs_check_item(KEY_ACCOUNT_ID, CCS_CONFIG_ITEM);
JimCarver 0:6b753f761943 1038 // Do not call delete if KEY does not exist.
JimCarver 0:6b753f761943 1039 if ((check_status == CCS_STATUS_KEY_DOESNT_EXIST) || (check_status == CCS_STATUS_ERROR)) {
JimCarver 0:6b753f761943 1040 tr_debug("No KEY_ACCOUNT_ID stored.");
JimCarver 0:6b753f761943 1041 } else {
JimCarver 0:6b753f761943 1042 ccs_delete_item(KEY_ACCOUNT_ID, CCS_CONFIG_ITEM);
JimCarver 0:6b753f761943 1043 // AccountID optional so don't fail if unable to store
JimCarver 0:6b753f761943 1044 ccs_set_item(KEY_ACCOUNT_ID,
JimCarver 0:6b753f761943 1045 (const uint8_t*)_endpoint_info.account_id.c_str(),
JimCarver 0:6b753f761943 1046 (size_t)_endpoint_info.account_id.size(),
JimCarver 0:6b753f761943 1047 CCS_CONFIG_ITEM);
JimCarver 0:6b753f761943 1048 }
JimCarver 0:6b753f761943 1049 }
JimCarver 0:6b753f761943 1050
JimCarver 0:6b753f761943 1051 if (status == CCS_STATUS_SUCCESS) {
JimCarver 0:6b753f761943 1052 status = ccs_set_item(g_fcc_lwm2m_server_uri_name,
JimCarver 0:6b753f761943 1053 (const uint8_t*)security->resource_value_string(M2MSecurity::M2MServerUri, m2m_id).c_str(),
JimCarver 0:6b753f761943 1054 (size_t)security->resource_value_string(M2MSecurity::M2MServerUri, m2m_id).size(),
JimCarver 0:6b753f761943 1055 CCS_CONFIG_ITEM);
JimCarver 0:6b753f761943 1056 }
JimCarver 0:6b753f761943 1057
JimCarver 0:6b753f761943 1058 M2MDevice *device = M2MInterfaceFactory::create_device();
JimCarver 0:6b753f761943 1059 if (status == CCS_STATUS_SUCCESS && device) {
JimCarver 0:6b753f761943 1060 String temp = "";
JimCarver 0:6b753f761943 1061 uint32_t currenttime = (uint32_t)device->resource_value_int(M2MDevice::CurrentTime, 0);
JimCarver 0:6b753f761943 1062 uint8_t data[4];
JimCarver 0:6b753f761943 1063 memcpy(data, &currenttime, 4);
JimCarver 0:6b753f761943 1064 ccs_delete_item(g_fcc_current_time_parameter_name, CCS_CONFIG_ITEM);
JimCarver 0:6b753f761943 1065 ccs_set_item(g_fcc_current_time_parameter_name, data, 4, CCS_CONFIG_ITEM);
JimCarver 0:6b753f761943 1066
JimCarver 0:6b753f761943 1067 temp = device->resource_value_string(M2MDevice::Timezone, 0);
JimCarver 0:6b753f761943 1068 if (temp.size() > 0) {
JimCarver 0:6b753f761943 1069 ccs_delete_item(g_fcc_device_time_zone_parameter_name, CCS_CONFIG_ITEM);
JimCarver 0:6b753f761943 1070 ccs_set_item(g_fcc_device_time_zone_parameter_name, (const uint8_t*)temp.c_str(), temp.size(), CCS_CONFIG_ITEM);
JimCarver 0:6b753f761943 1071 }
JimCarver 0:6b753f761943 1072
JimCarver 0:6b753f761943 1073 temp = device->resource_value_string(M2MDevice::UTCOffset, 0);
JimCarver 0:6b753f761943 1074 if (temp.size() > 0) {
JimCarver 0:6b753f761943 1075 ccs_delete_item(g_fcc_offset_from_utc_parameter_name, CCS_CONFIG_ITEM);
JimCarver 0:6b753f761943 1076 ccs_set_item(g_fcc_offset_from_utc_parameter_name, (const uint8_t*)temp.c_str(), temp.size(), CCS_CONFIG_ITEM);
JimCarver 0:6b753f761943 1077 }
JimCarver 0:6b753f761943 1078
JimCarver 0:6b753f761943 1079 status = CCS_STATUS_SUCCESS;
JimCarver 0:6b753f761943 1080 }
JimCarver 0:6b753f761943 1081 else {
JimCarver 0:6b753f761943 1082 tr_debug("No device object to store!");
JimCarver 0:6b753f761943 1083 }
JimCarver 0:6b753f761943 1084
JimCarver 0:6b753f761943 1085 return status;
JimCarver 0:6b753f761943 1086 }
JimCarver 0:6b753f761943 1087
JimCarver 0:6b753f761943 1088 ccs_status_e ConnectorClient::set_bootstrap_credentials(M2MSecurity *security)
JimCarver 0:6b753f761943 1089 {
JimCarver 0:6b753f761943 1090 tr_debug("ConnectorClient::set_bootstrap_credentials");
JimCarver 0:6b753f761943 1091 ccs_status_e status = CCS_STATUS_ERROR;
JimCarver 0:6b753f761943 1092
JimCarver 0:6b753f761943 1093 size_t buffer_size = MAX_CERTIFICATE_SIZE;
JimCarver 0:6b753f761943 1094 uint8_t key[MAX_CERTIFICATE_SIZE];
JimCarver 0:6b753f761943 1095 uint8_t *key_ptr = (uint8_t*)&key;
JimCarver 0:6b753f761943 1096
JimCarver 0:6b753f761943 1097 int32_t bs_id = security->get_security_instance_id(M2MSecurity::Bootstrap);
JimCarver 0:6b753f761943 1098 if (bs_id == -1) {
JimCarver 0:6b753f761943 1099 return status;
JimCarver 0:6b753f761943 1100 }
JimCarver 0:6b753f761943 1101
JimCarver 0:6b753f761943 1102 // TODO! Update to use chain api
JimCarver 0:6b753f761943 1103 if (security->resource_value_buffer(M2MSecurity::PublicKey, key_ptr, bs_id, &buffer_size) != 0) {
JimCarver 0:6b753f761943 1104 return status;
JimCarver 0:6b753f761943 1105 }
JimCarver 0:6b753f761943 1106
JimCarver 0:6b753f761943 1107 if (buffer_size) {
JimCarver 0:6b753f761943 1108 ccs_delete_item(g_fcc_bootstrap_device_certificate_name, CCS_CERTIFICATE_ITEM);
JimCarver 0:6b753f761943 1109 status = ccs_set_item(g_fcc_bootstrap_device_certificate_name,
JimCarver 0:6b753f761943 1110 key_ptr,
JimCarver 0:6b753f761943 1111 buffer_size,
JimCarver 0:6b753f761943 1112 CCS_CERTIFICATE_ITEM);
JimCarver 0:6b753f761943 1113 buffer_size = MAX_CERTIFICATE_SIZE;
JimCarver 0:6b753f761943 1114 }
JimCarver 0:6b753f761943 1115
JimCarver 0:6b753f761943 1116 if (status == CCS_STATUS_SUCCESS) {
JimCarver 0:6b753f761943 1117 if (security->resource_value_buffer(M2MSecurity::Secretkey, key_ptr, bs_id, &buffer_size) != 0) {
JimCarver 0:6b753f761943 1118 status = CCS_STATUS_ERROR;
JimCarver 0:6b753f761943 1119 buffer_size = 0;
JimCarver 0:6b753f761943 1120 }
JimCarver 0:6b753f761943 1121
JimCarver 0:6b753f761943 1122 if(buffer_size) {
JimCarver 0:6b753f761943 1123 ccs_delete_item(g_fcc_bootstrap_device_private_key_name, CCS_PRIVATE_KEY_ITEM);
JimCarver 0:6b753f761943 1124 status = ccs_set_item(g_fcc_bootstrap_device_private_key_name,
JimCarver 0:6b753f761943 1125 key_ptr,
JimCarver 0:6b753f761943 1126 buffer_size,
JimCarver 0:6b753f761943 1127 CCS_PRIVATE_KEY_ITEM);
JimCarver 0:6b753f761943 1128 buffer_size = MAX_CERTIFICATE_SIZE;
JimCarver 0:6b753f761943 1129 }
JimCarver 0:6b753f761943 1130 }
JimCarver 0:6b753f761943 1131
JimCarver 0:6b753f761943 1132 if (status == CCS_STATUS_SUCCESS) {
JimCarver 0:6b753f761943 1133 if (security->resource_value_buffer(M2MSecurity::ServerPublicKey, key_ptr, bs_id, &buffer_size) != 0) {
JimCarver 0:6b753f761943 1134 status = CCS_STATUS_ERROR;
JimCarver 0:6b753f761943 1135 buffer_size = 0;
JimCarver 0:6b753f761943 1136 }
JimCarver 0:6b753f761943 1137
JimCarver 0:6b753f761943 1138 if (buffer_size) {
JimCarver 0:6b753f761943 1139 ccs_delete_item(g_fcc_bootstrap_server_ca_certificate_name, CCS_CERTIFICATE_ITEM);
JimCarver 0:6b753f761943 1140 status = ccs_set_item(g_fcc_bootstrap_server_ca_certificate_name,
JimCarver 0:6b753f761943 1141 key_ptr,
JimCarver 0:6b753f761943 1142 buffer_size,
JimCarver 0:6b753f761943 1143 CCS_CERTIFICATE_ITEM);
JimCarver 0:6b753f761943 1144 }
JimCarver 0:6b753f761943 1145 }
JimCarver 0:6b753f761943 1146
JimCarver 0:6b753f761943 1147 if(status == CCS_STATUS_SUCCESS) {
JimCarver 0:6b753f761943 1148 ccs_delete_item(g_fcc_bootstrap_server_uri_name, CCS_CONFIG_ITEM);
JimCarver 0:6b753f761943 1149 status = ccs_set_item(g_fcc_bootstrap_server_uri_name,
JimCarver 0:6b753f761943 1150 (const uint8_t*)security->resource_value_string(M2MSecurity::M2MServerUri, bs_id).c_str(),
JimCarver 0:6b753f761943 1151 (size_t)security->resource_value_string(M2MSecurity::M2MServerUri, bs_id).size(),
JimCarver 0:6b753f761943 1152 CCS_CONFIG_ITEM);
JimCarver 0:6b753f761943 1153 }
JimCarver 0:6b753f761943 1154
JimCarver 0:6b753f761943 1155 return status;
JimCarver 0:6b753f761943 1156 }
JimCarver 0:6b753f761943 1157
JimCarver 0:6b753f761943 1158 ccs_status_e ConnectorClient::store_bootstrap_address(M2MSecurity *security)
JimCarver 0:6b753f761943 1159 {
JimCarver 0:6b753f761943 1160 tr_debug("ConnectorClient::store_bootstrap_address");
JimCarver 0:6b753f761943 1161 ccs_status_e status = CCS_STATUS_ERROR;
JimCarver 0:6b753f761943 1162
JimCarver 0:6b753f761943 1163 const uint8_t *srv_address = NULL;
JimCarver 0:6b753f761943 1164 int32_t bs_id = security->get_security_instance_id(M2MSecurity::Bootstrap);
JimCarver 0:6b753f761943 1165 if (bs_id == -1) {
JimCarver 0:6b753f761943 1166 return status;
JimCarver 0:6b753f761943 1167 }
JimCarver 0:6b753f761943 1168
JimCarver 0:6b753f761943 1169 uint32_t srv_address_size = security->resource_value_buffer(M2MSecurity::M2MServerUri, srv_address, bs_id);
JimCarver 0:6b753f761943 1170
JimCarver 0:6b753f761943 1171 if(srv_address) {
JimCarver 0:6b753f761943 1172 ccs_delete_item(g_fcc_bootstrap_server_uri_name, CCS_CONFIG_ITEM);
JimCarver 0:6b753f761943 1173 status = ccs_set_item(g_fcc_bootstrap_server_uri_name,
JimCarver 0:6b753f761943 1174 srv_address,
JimCarver 0:6b753f761943 1175 (size_t)srv_address_size,
JimCarver 0:6b753f761943 1176 CCS_CONFIG_ITEM);
JimCarver 0:6b753f761943 1177 }
JimCarver 0:6b753f761943 1178
JimCarver 0:6b753f761943 1179 return status;
JimCarver 0:6b753f761943 1180 }
JimCarver 0:6b753f761943 1181
JimCarver 0:6b753f761943 1182 ccs_status_e ConnectorClient::clear_first_to_claim()
JimCarver 0:6b753f761943 1183 {
JimCarver 0:6b753f761943 1184 tr_debug("ConnectorClient::clear_first_to_claim");
JimCarver 0:6b753f761943 1185 return ccs_delete_item(KEY_FIRST_TO_CLAIM, CCS_CONFIG_ITEM);
JimCarver 0:6b753f761943 1186 }
JimCarver 0:6b753f761943 1187
JimCarver 0:6b753f761943 1188
JimCarver 0:6b753f761943 1189 const ConnectorClientEndpointInfo *ConnectorClient::endpoint_info() const
JimCarver 0:6b753f761943 1190 {
JimCarver 0:6b753f761943 1191 return &_endpoint_info;
JimCarver 0:6b753f761943 1192 }
JimCarver 0:6b753f761943 1193
JimCarver 0:6b753f761943 1194 bool ConnectorClient::bootstrap_credentials_stored_in_kcm()
JimCarver 0:6b753f761943 1195 {
JimCarver 0:6b753f761943 1196 size_t real_size = 0;
JimCarver 0:6b753f761943 1197 ccs_status_e success = ccs_item_size(g_fcc_bootstrap_server_uri_name, &real_size, CCS_CONFIG_ITEM);
JimCarver 0:6b753f761943 1198 // Return true if bootstrap uri exists in KCM
JimCarver 0:6b753f761943 1199 if ((success == CCS_STATUS_SUCCESS) && real_size > 0) {
JimCarver 0:6b753f761943 1200 return true;
JimCarver 0:6b753f761943 1201 } else {
JimCarver 0:6b753f761943 1202 return false;
JimCarver 0:6b753f761943 1203 }
JimCarver 0:6b753f761943 1204 }
JimCarver 0:6b753f761943 1205
JimCarver 0:6b753f761943 1206 bool ConnectorClient::is_first_to_claim()
JimCarver 0:6b753f761943 1207 {
JimCarver 0:6b753f761943 1208 size_t real_size = 0;
JimCarver 0:6b753f761943 1209 uint8_t data[CONFIG_BOOLEAN_ITEM_SIZE] = {0};
JimCarver 0:6b753f761943 1210 uint32_t value = 0;
JimCarver 0:6b753f761943 1211 ccs_status_e status = ccs_get_item(KEY_FIRST_TO_CLAIM, data, CONFIG_BOOLEAN_ITEM_SIZE, &real_size, CCS_CONFIG_ITEM);
JimCarver 0:6b753f761943 1212 if (status == CCS_STATUS_SUCCESS) {
JimCarver 0:6b753f761943 1213 memcpy(&value, data, CONFIG_BOOLEAN_ITEM_SIZE);
JimCarver 0:6b753f761943 1214 // Return true if first to claim is set
JimCarver 0:6b753f761943 1215 if (value == 1) {
JimCarver 0:6b753f761943 1216 return true;
JimCarver 0:6b753f761943 1217 }
JimCarver 0:6b753f761943 1218 }
JimCarver 0:6b753f761943 1219 return false;
JimCarver 0:6b753f761943 1220 }
JimCarver 0:6b753f761943 1221
JimCarver 0:6b753f761943 1222 void ConnectorClient::timer_expired(M2MTimerObserver::Type type)
JimCarver 0:6b753f761943 1223 {
JimCarver 0:6b753f761943 1224 if (type == M2MTimerObserver::BootstrapFlowTimer) {
JimCarver 0:6b753f761943 1225 start_bootstrap();
JimCarver 0:6b753f761943 1226 }
JimCarver 0:6b753f761943 1227 }
JimCarver 0:6b753f761943 1228
JimCarver 0:6b753f761943 1229 #ifndef MBED_CLIENT_DISABLE_EST_FEATURE
JimCarver 0:6b753f761943 1230 void ConnectorClient::est_enrollment_result(bool success,
JimCarver 0:6b753f761943 1231 const uint8_t *payload_ptr,
JimCarver 0:6b753f761943 1232 const uint16_t payload_len)
JimCarver 0:6b753f761943 1233 {
JimCarver 0:6b753f761943 1234 tr_debug("ConnectorClient::est_enrollment_result - %s", success ? "successful" : "failed");
JimCarver 0:6b753f761943 1235 tr_debug("ConnectorClient::est_enrollment_result - PublicKey size %d", (int)payload_len);
JimCarver 0:6b753f761943 1236
JimCarver 0:6b753f761943 1237 assert(_security != NULL);
JimCarver 0:6b753f761943 1238 int32_t m2m_id = _security->get_security_instance_id(M2MSecurity::M2MServer);
JimCarver 0:6b753f761943 1239 StartupSubStateRegistration state = State_EST_Failure;
JimCarver 0:6b753f761943 1240
JimCarver 0:6b753f761943 1241 if (success && payload_ptr && payload_len > 0 && m2m_id >= 0) {
JimCarver 0:6b753f761943 1242 const uint8_t *ptr = payload_ptr;
JimCarver 0:6b753f761943 1243 tr_debug("Payload start: %s", tr_array(payload_ptr, 10));
JimCarver 0:6b753f761943 1244 ccs_status_e ccs_status = ccs_parse_cert_chain_and_store((const uint8_t*)g_fcc_lwm2m_device_certificate_name,
JimCarver 0:6b753f761943 1245 strlen(g_fcc_lwm2m_device_certificate_name),
JimCarver 0:6b753f761943 1246 payload_ptr,
JimCarver 0:6b753f761943 1247 payload_len);
JimCarver 0:6b753f761943 1248 if (ccs_status != CCS_STATUS_SUCCESS) {
JimCarver 0:6b753f761943 1249 tr_error("ConnectorClient::est_enrollment_result - storing certificate chain failed!");
JimCarver 0:6b753f761943 1250 }
JimCarver 0:6b753f761943 1251 else {
JimCarver 0:6b753f761943 1252 tr_info("ConnectorClient::est_enrollment_result() - Storing lwm2m credentials");
JimCarver 0:6b753f761943 1253 if (set_connector_credentials(_security) == CCS_STATUS_SUCCESS) {
JimCarver 0:6b753f761943 1254 state = State_EST_Success;
JimCarver 0:6b753f761943 1255 }
JimCarver 0:6b753f761943 1256 }
JimCarver 0:6b753f761943 1257
JimCarver 0:6b753f761943 1258 }
JimCarver 0:6b753f761943 1259
JimCarver 0:6b753f761943 1260 internal_event(state);
JimCarver 0:6b753f761943 1261 }
JimCarver 0:6b753f761943 1262
JimCarver 0:6b753f761943 1263 void ConnectorClient::est_post_data_cb(const uint8_t *buffer,
JimCarver 0:6b753f761943 1264 size_t buffer_size,
JimCarver 0:6b753f761943 1265 size_t total_size,
JimCarver 0:6b753f761943 1266 void *context)
JimCarver 0:6b753f761943 1267 {
JimCarver 0:6b753f761943 1268 ConnectorClient *cc = static_cast<ConnectorClient*>(context);
JimCarver 0:6b753f761943 1269 assert(cc);
JimCarver 0:6b753f761943 1270 cc->est_enrollment_result(true, buffer, buffer_size);
JimCarver 0:6b753f761943 1271
JimCarver 0:6b753f761943 1272 }
JimCarver 0:6b753f761943 1273
JimCarver 0:6b753f761943 1274 void ConnectorClient::est_post_data_error_cb(get_data_req_error_t error_code,
JimCarver 0:6b753f761943 1275 void *context)
JimCarver 0:6b753f761943 1276 {
JimCarver 0:6b753f761943 1277 ConnectorClient *cc = static_cast<ConnectorClient*>(context);
JimCarver 0:6b753f761943 1278 assert(cc);
JimCarver 0:6b753f761943 1279 cc->est_enrollment_result(false, NULL, 0);
JimCarver 0:6b753f761943 1280 }
JimCarver 0:6b753f761943 1281 #endif /* !MBED_CLIENT_DISABLE_EST_FEATURE */
JimCarver 0:6b753f761943 1282
JimCarver 0:6b753f761943 1283
JimCarver 0:6b753f761943 1284 M2MInterface::BindingMode ConnectorClient::transport_mode()
JimCarver 0:6b753f761943 1285 {
JimCarver 0:6b753f761943 1286 #ifdef MBED_CLOUD_CLIENT_TRANSPORT_MODE_UDP
JimCarver 0:6b753f761943 1287 return M2MInterface::UDP;
JimCarver 0:6b753f761943 1288 #elif defined MBED_CLOUD_CLIENT_TRANSPORT_MODE_TCP
JimCarver 0:6b753f761943 1289 return M2MInterface::TCP;
JimCarver 0:6b753f761943 1290 #elif defined MBED_CLOUD_CLIENT_TRANSPORT_MODE_UDP_QUEUE
JimCarver 0:6b753f761943 1291 return M2MInterface::UDP_QUEUE;
JimCarver 0:6b753f761943 1292 #elif defined MBED_CLOUD_CLIENT_TRANSPORT_MODE_TCP_QUEUE
JimCarver 0:6b753f761943 1293 return M2MInterface::TCP_QUEUE;
JimCarver 0:6b753f761943 1294 #else
JimCarver 0:6b753f761943 1295 return M2MInterface::UDP;
JimCarver 0:6b753f761943 1296 #endif
JimCarver 0:6b753f761943 1297 }
JimCarver 0:6b753f761943 1298
JimCarver 0:6b753f761943 1299 void ConnectorClient::init_security_object()
JimCarver 0:6b753f761943 1300 {
JimCarver 0:6b753f761943 1301 if (_security) {
JimCarver 0:6b753f761943 1302 for (int i = 0; i <= M2MSecurity::Bootstrap; i++) {
JimCarver 0:6b753f761943 1303 // _security->create_object_instance() returns NULL if object already exists
JimCarver 0:6b753f761943 1304 if (_security->create_object_instance((M2MSecurity::ServerType)i)) {
JimCarver 0:6b753f761943 1305 M2MResource* res = _security->get_resource(M2MSecurity::ServerPublicKey, i);
JimCarver 0:6b753f761943 1306 if (res) {
JimCarver 0:6b753f761943 1307 res->set_resource_read_callback(read_security_object_data_from_kcm, this);
JimCarver 0:6b753f761943 1308 res->set_resource_write_callback(write_security_object_data_to_kcm, this);
JimCarver 0:6b753f761943 1309 }
JimCarver 0:6b753f761943 1310
JimCarver 0:6b753f761943 1311 res = _security->get_resource(M2MSecurity::PublicKey, i);
JimCarver 0:6b753f761943 1312 if (res) {
JimCarver 0:6b753f761943 1313 res->set_resource_read_callback(read_security_object_data_from_kcm, this);
JimCarver 0:6b753f761943 1314 res->set_resource_write_callback(write_security_object_data_to_kcm, this);
JimCarver 0:6b753f761943 1315 }
JimCarver 0:6b753f761943 1316
JimCarver 0:6b753f761943 1317 res = _security->get_resource(M2MSecurity::Secretkey, i);
JimCarver 0:6b753f761943 1318 if (res) {
JimCarver 0:6b753f761943 1319 res->set_resource_read_callback(read_security_object_data_from_kcm, this);
JimCarver 0:6b753f761943 1320 res->set_resource_write_callback(write_security_object_data_to_kcm, this);
JimCarver 0:6b753f761943 1321 }
JimCarver 0:6b753f761943 1322
JimCarver 0:6b753f761943 1323 res = _security->get_resource(M2MSecurity::OpenCertificateChain, i);
JimCarver 0:6b753f761943 1324 if (res) {
JimCarver 0:6b753f761943 1325 res->set_resource_read_callback(open_certificate_chain_callback, this);
JimCarver 0:6b753f761943 1326 }
JimCarver 0:6b753f761943 1327
JimCarver 0:6b753f761943 1328 res = _security->get_resource(M2MSecurity::ReadDeviceCertificateChain, i);
JimCarver 0:6b753f761943 1329 if (res) {
JimCarver 0:6b753f761943 1330 res->set_resource_read_callback(read_certificate_chain_callback, this);
JimCarver 0:6b753f761943 1331 }
JimCarver 0:6b753f761943 1332
JimCarver 0:6b753f761943 1333 res = _security->get_resource(M2MSecurity::CloseCertificateChain, i);
JimCarver 0:6b753f761943 1334 if (res) {
JimCarver 0:6b753f761943 1335 res->set_resource_read_callback(close_certificate_chain_callback, this);
JimCarver 0:6b753f761943 1336 }
JimCarver 0:6b753f761943 1337 }
JimCarver 0:6b753f761943 1338 }
JimCarver 0:6b753f761943 1339 }
JimCarver 0:6b753f761943 1340 }
JimCarver 0:6b753f761943 1341
JimCarver 0:6b753f761943 1342 void *ConnectorClient::certificate_chain_handle() const
JimCarver 0:6b753f761943 1343 {
JimCarver 0:6b753f761943 1344 return _certificate_chain_handle;
JimCarver 0:6b753f761943 1345 }
JimCarver 0:6b753f761943 1346
JimCarver 0:6b753f761943 1347 void ConnectorClient::set_certificate_chain_handle(void *cert_handle)
JimCarver 0:6b753f761943 1348 {
JimCarver 0:6b753f761943 1349 _certificate_chain_handle = cert_handle;
JimCarver 0:6b753f761943 1350 }