Jim Carver
/
mbed-cloud-workshop-connect
Fork for workshops
simple-mbed-cloud-client/mbed-cloud-client/source/ConnectorClient.cpp@0:6b753f761943, 2018-10-12 (annotated)
- Committer:
- JimCarver
- Date:
- Fri Oct 12 21:22:49 2018 +0000
- Revision:
- 0:6b753f761943
Initial commit
Who changed what in which revision?
User | Revision | Line number | New 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, ¤ttime, 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 | } |