Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
m2msecurity.cpp
00001 /* 00002 * Copyright (c) 2015 ARM Limited. All rights reserved. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * Licensed under the Apache License, Version 2.0 (the License); you may 00005 * not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an AS IS BASIS, WITHOUT 00012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #include "mbed-client/m2msecurity.h" 00017 #include "mbed-client/m2mconstants.h" 00018 #include "mbed-client/m2mobject.h" 00019 #include "mbed-client/m2mobjectinstance.h" 00020 #include "mbed-client/m2mresource.h" 00021 #include "mbed-client/m2mstring.h" 00022 #include "mbed-trace/mbed_trace.h" 00023 00024 #include <stdlib.h> 00025 00026 #define TRACE_GROUP "mClt" 00027 00028 #define BUFFER_SIZE 21 00029 00030 // Default instance id's that server uses 00031 #define DEFAULT_M2M_INSTANCE 0 00032 #define DEFAULT_BOOTSTRAP_INSTANCE 1 00033 00034 M2MSecurity* M2MSecurity::_instance = NULL; 00035 00036 M2MSecurity* M2MSecurity::get_instance() 00037 { 00038 if (_instance == NULL) { 00039 _instance = new M2MSecurity(M2MServer); 00040 } 00041 return _instance; 00042 } 00043 00044 void M2MSecurity::delete_instance() 00045 { 00046 delete _instance; 00047 _instance = NULL; 00048 } 00049 00050 00051 M2MSecurity::M2MSecurity(ServerType ser_type) 00052 : M2MObject(M2M_SECURITY_ID, stringdup(M2M_SECURITY_ID)) 00053 { 00054 } 00055 00056 M2MSecurity::~M2MSecurity() 00057 { 00058 } 00059 00060 M2MObjectInstance* M2MSecurity::create_object_instance(ServerType server_type) 00061 { 00062 uint16_t instance_id = DEFAULT_M2M_INSTANCE; 00063 if (server_type == Bootstrap) { 00064 instance_id = DEFAULT_BOOTSTRAP_INSTANCE; 00065 } 00066 00067 M2MObjectInstance *server_instance = M2MObject::object_instance(instance_id); 00068 if (server_instance != NULL) { 00069 // Instance already exists, return NULL 00070 return NULL; 00071 } 00072 00073 server_instance = M2MObject::create_object_instance(instance_id); 00074 if (server_instance) { 00075 M2MResource* res = server_instance->create_dynamic_resource(SECURITY_M2M_SERVER_URI, 00076 OMA_RESOURCE_TYPE, 00077 M2MResourceInstance::STRING, 00078 false); 00079 if (res) { 00080 res->set_operation(M2MBase::NOT_ALLOWED); 00081 } 00082 res = server_instance->create_dynamic_resource(SECURITY_BOOTSTRAP_SERVER, 00083 OMA_RESOURCE_TYPE, 00084 M2MResourceInstance::BOOLEAN, 00085 false); 00086 if (res) { 00087 res->set_operation(M2MBase::NOT_ALLOWED); 00088 res->set_value((int)server_type); 00089 } 00090 res = server_instance->create_dynamic_resource(SECURITY_SECURITY_MODE, 00091 OMA_RESOURCE_TYPE, 00092 M2MResourceInstance::INTEGER, 00093 false); 00094 if (res) { 00095 res->set_operation(M2MBase::NOT_ALLOWED); 00096 } 00097 res = server_instance->create_dynamic_resource(SECURITY_PUBLIC_KEY, 00098 OMA_RESOURCE_TYPE, 00099 M2MResourceInstance::OPAQUE, 00100 false); 00101 if (res) { 00102 res->set_operation(M2MBase::NOT_ALLOWED); 00103 } 00104 res = server_instance->create_dynamic_resource(SECURITY_SERVER_PUBLIC_KEY, 00105 OMA_RESOURCE_TYPE, 00106 M2MResourceInstance::OPAQUE, 00107 false); 00108 if (res) { 00109 res->set_operation(M2MBase::NOT_ALLOWED); 00110 } 00111 res = server_instance->create_dynamic_resource(SECURITY_SECRET_KEY, 00112 OMA_RESOURCE_TYPE, 00113 M2MResourceInstance::OPAQUE, 00114 false); 00115 if (res) { 00116 res->set_operation(M2MBase::NOT_ALLOWED); 00117 } 00118 00119 res = server_instance->create_dynamic_resource(SECURITY_OPEN_CERTIFICATE_CHAIN, 00120 OMA_RESOURCE_TYPE, 00121 M2MResourceInstance::OPAQUE, 00122 false); 00123 if (res) { 00124 res->set_operation(M2MBase::NOT_ALLOWED); 00125 } 00126 00127 res = server_instance->create_dynamic_resource(SECURITY_CLOSE_CERTIFICATE_CHAIN, 00128 OMA_RESOURCE_TYPE, 00129 M2MResourceInstance::OPAQUE, 00130 false); 00131 if (res) { 00132 res->set_operation(M2MBase::NOT_ALLOWED); 00133 } 00134 00135 res = server_instance->create_dynamic_resource(SECURITY_READ_CERTIFICATE_CHAIN, 00136 OMA_RESOURCE_TYPE, 00137 M2MResourceInstance::OPAQUE, 00138 false); 00139 if (res) { 00140 res->set_operation(M2MBase::NOT_ALLOWED); 00141 } 00142 00143 if (M2MSecurity::M2MServer == server_type) { 00144 res = server_instance->create_dynamic_resource(SECURITY_SHORT_SERVER_ID, 00145 OMA_RESOURCE_TYPE, 00146 M2MResourceInstance::INTEGER, 00147 false); 00148 if (res) { 00149 res->set_operation(M2MBase::NOT_ALLOWED); 00150 } 00151 } 00152 } 00153 return server_instance; 00154 } 00155 00156 void M2MSecurity::remove_security_instances() 00157 { 00158 int32_t instance_id = _instance->get_security_instance_id(M2MSecurity::Bootstrap); 00159 if (instance_id >= 0) { 00160 _instance->remove_object_instance(instance_id); 00161 } 00162 instance_id = _instance->get_security_instance_id(M2MSecurity::M2MServer); 00163 if (instance_id >= 0) { 00164 _instance->remove_object_instance(instance_id); 00165 } 00166 } 00167 00168 M2MResource* M2MSecurity::create_resource(SecurityResource resource, uint32_t value, uint16_t instance_id) 00169 { 00170 M2MResource* res = NULL; 00171 M2MObjectInstance *server_instance = M2MObject::object_instance(instance_id); 00172 if (server_instance == NULL) { 00173 return NULL; 00174 } 00175 00176 const char* security_id_ptr = ""; 00177 if (!is_resource_present(resource, instance_id)) { 00178 switch(resource) { 00179 case SMSSecurityMode: 00180 security_id_ptr = SECURITY_SMS_SECURITY_MODE; 00181 break; 00182 case M2MServerSMSNumber: 00183 security_id_ptr = SECURITY_M2M_SERVER_SMS_NUMBER; 00184 break; 00185 case ShortServerID: 00186 security_id_ptr = SECURITY_SHORT_SERVER_ID; 00187 break; 00188 case ClientHoldOffTime: 00189 security_id_ptr = SECURITY_CLIENT_HOLD_OFF_TIME; 00190 break; 00191 default: 00192 break; 00193 } 00194 } 00195 00196 const String security_id(security_id_ptr); 00197 00198 if (!security_id.empty()) { 00199 if (server_instance) { 00200 res = server_instance->create_dynamic_resource(security_id,OMA_RESOURCE_TYPE, 00201 M2MResourceInstance::INTEGER, 00202 false); 00203 00204 if (res) { 00205 res->set_operation(M2MBase::NOT_ALLOWED); 00206 res->set_value(value); 00207 } 00208 } 00209 } 00210 return res; 00211 } 00212 00213 bool M2MSecurity::delete_resource(SecurityResource resource, uint16_t instance_id) 00214 { 00215 bool success = false; 00216 const char* security_id_ptr; 00217 M2MObjectInstance *server_instance = M2MObject::object_instance(instance_id); 00218 if (server_instance == NULL) { 00219 return NULL; 00220 } 00221 switch(resource) { 00222 case SMSSecurityMode: 00223 security_id_ptr = SECURITY_SMS_SECURITY_MODE; 00224 break; 00225 case M2MServerSMSNumber: 00226 security_id_ptr = SECURITY_M2M_SERVER_SMS_NUMBER; 00227 break; 00228 case ShortServerID: 00229 if (M2MSecurity::Bootstrap == server_type(instance_id)) { 00230 security_id_ptr = SECURITY_SHORT_SERVER_ID; 00231 } else { 00232 security_id_ptr = NULL; 00233 } 00234 break; 00235 case ClientHoldOffTime: 00236 security_id_ptr = SECURITY_CLIENT_HOLD_OFF_TIME; 00237 break; 00238 default: 00239 // Others are mandatory resources hence cannot be deleted. 00240 security_id_ptr = NULL; 00241 break; 00242 } 00243 00244 if (security_id_ptr) { 00245 if (server_instance) { 00246 success = server_instance->remove_resource(security_id_ptr); 00247 } 00248 } 00249 return success; 00250 } 00251 00252 bool M2MSecurity::set_resource_value(SecurityResource resource, 00253 const String &value, 00254 uint16_t instance_id) 00255 { 00256 bool success = false; 00257 if (M2MSecurity::M2MServerUri == resource) { 00258 M2MResource* res = get_resource(resource, instance_id); 00259 if (res) { 00260 success = res->set_value((const uint8_t*)value.c_str(),(uint32_t)value.length()); 00261 } 00262 } 00263 return success; 00264 } 00265 00266 bool M2MSecurity::set_resource_value(SecurityResource resource, 00267 uint32_t value, 00268 uint16_t instance_id) 00269 { 00270 bool success = false; 00271 M2MResource* res = get_resource(resource, instance_id); 00272 if (res) { 00273 if (M2MSecurity::SecurityMode == resource || 00274 M2MSecurity::SMSSecurityMode == resource || 00275 M2MSecurity::M2MServerSMSNumber == resource || 00276 M2MSecurity::ShortServerID == resource || 00277 M2MSecurity::BootstrapServer == resource || 00278 M2MSecurity::ClientHoldOffTime == resource) { 00279 success = res->set_value(value); 00280 00281 } 00282 } 00283 return success; 00284 } 00285 00286 bool M2MSecurity::set_resource_value(SecurityResource resource, 00287 const uint8_t *value, 00288 const uint16_t length, 00289 uint16_t instance_id) 00290 { 00291 bool success = false; 00292 M2MResource* res = get_resource(resource, instance_id); 00293 if (res) { 00294 if (M2MSecurity::PublicKey == resource || 00295 M2MSecurity::ServerPublicKey == resource || 00296 M2MSecurity::Secretkey == resource || 00297 M2MSecurity::M2MServerUri == resource) { 00298 success = res->set_value(value,length); 00299 } 00300 } 00301 return success; 00302 } 00303 00304 String M2MSecurity::resource_value_string(SecurityResource resource, uint16_t instance_id) const 00305 { 00306 String value = ""; 00307 M2MResource* res = get_resource(resource, instance_id); 00308 if (res) { 00309 if (M2MSecurity::M2MServerUri == resource) { 00310 value = res->get_value_string(); 00311 } 00312 } 00313 return value; 00314 } 00315 00316 int M2MSecurity::resource_value_buffer(SecurityResource resource, 00317 uint8_t *&data, 00318 uint16_t instance_id, 00319 size_t *buffer_len) const 00320 { 00321 M2MResource* res = get_resource(resource, instance_id); 00322 if (res) { 00323 if (M2MSecurity::PublicKey == resource || 00324 M2MSecurity::ServerPublicKey == resource || 00325 M2MSecurity::Secretkey == resource || 00326 M2MSecurity::OpenCertificateChain == resource || 00327 M2MSecurity::CloseCertificateChain == resource || 00328 M2MSecurity::ReadDeviceCertificateChain == resource) { 00329 return res->read_resource_value(*(M2MResourceBase *)res, data, buffer_len); 00330 } 00331 } 00332 00333 return -1; 00334 } 00335 00336 uint32_t M2MSecurity::resource_value_buffer(SecurityResource resource, 00337 const uint8_t *&data, 00338 uint16_t instance_id) const 00339 { 00340 uint32_t size = 0; 00341 M2MResource* res = get_resource(resource, instance_id); 00342 if (res) { 00343 if (M2MSecurity::PublicKey == resource || 00344 M2MSecurity::ServerPublicKey == resource || 00345 M2MSecurity::Secretkey == resource) { 00346 data = res->value(); 00347 size = res->value_length(); 00348 } 00349 } 00350 return size; 00351 } 00352 00353 00354 uint32_t M2MSecurity::resource_value_int(SecurityResource resource, uint16_t instance_id) const 00355 { 00356 uint32_t value = 0; 00357 M2MResource* res = get_resource(resource, instance_id); 00358 if (res) { 00359 if (M2MSecurity::SecurityMode == resource || 00360 M2MSecurity::SMSSecurityMode == resource || 00361 M2MSecurity::M2MServerSMSNumber == resource || 00362 M2MSecurity::ShortServerID == resource || 00363 M2MSecurity::BootstrapServer == resource || 00364 M2MSecurity::ClientHoldOffTime == resource) { 00365 // note: the value may be 32bit int on 32b archs. 00366 value = res->get_value_int(); 00367 } 00368 } 00369 return value; 00370 } 00371 00372 bool M2MSecurity::is_resource_present(SecurityResource resource, uint16_t instance_id) const 00373 { 00374 bool success = false; 00375 M2MResource *res = get_resource(resource, instance_id); 00376 if (res) { 00377 success = true; 00378 } 00379 return success; 00380 } 00381 00382 uint16_t M2MSecurity::total_resource_count(uint16_t instance_id) const 00383 { 00384 uint16_t count = 0; 00385 M2MObjectInstance *server_instance = M2MObject::object_instance(instance_id); 00386 if (server_instance) { 00387 count = server_instance->resources().size(); 00388 } 00389 return count; 00390 } 00391 00392 M2MSecurity::ServerType M2MSecurity::server_type(uint16_t instance_id) const 00393 { 00394 uint32_t sec_mode = resource_value_int(M2MSecurity::BootstrapServer, instance_id); 00395 M2MSecurity::ServerType type = M2MSecurity::M2MServer; 00396 if (sec_mode == 1) { 00397 type = M2MSecurity::Bootstrap; 00398 } 00399 return type; 00400 } 00401 00402 M2MResource* M2MSecurity::get_resource(SecurityResource res, uint16_t instance_id) const 00403 { 00404 M2MResource* res_object = NULL; 00405 M2MObjectInstance *server_instance = M2MObject::object_instance(instance_id); 00406 if (server_instance == NULL) { 00407 return NULL; 00408 } 00409 00410 if (server_instance) { 00411 const char* res_name_ptr = NULL; 00412 switch(res) { 00413 case M2MServerUri: 00414 res_name_ptr = SECURITY_M2M_SERVER_URI; 00415 break; 00416 case BootstrapServer: 00417 res_name_ptr = SECURITY_BOOTSTRAP_SERVER; 00418 break; 00419 case SecurityMode: 00420 res_name_ptr = SECURITY_SECURITY_MODE; 00421 break; 00422 case PublicKey: 00423 res_name_ptr = SECURITY_PUBLIC_KEY; 00424 break; 00425 case ServerPublicKey: 00426 res_name_ptr = SECURITY_SERVER_PUBLIC_KEY; 00427 break; 00428 case Secretkey: 00429 res_name_ptr = SECURITY_SECRET_KEY; 00430 break; 00431 case SMSSecurityMode: 00432 res_name_ptr = SECURITY_SMS_SECURITY_MODE; 00433 break; 00434 case SMSBindingKey: 00435 res_name_ptr = SECURITY_SMS_BINDING_KEY; 00436 break; 00437 case SMSBindingSecretKey: 00438 res_name_ptr = SECURITY_SMS_BINDING_SECRET_KEY; 00439 break; 00440 case M2MServerSMSNumber: 00441 res_name_ptr = SECURITY_M2M_SERVER_SMS_NUMBER; 00442 break; 00443 case ShortServerID: 00444 res_name_ptr = SECURITY_SHORT_SERVER_ID; 00445 break; 00446 case ClientHoldOffTime: 00447 res_name_ptr = SECURITY_CLIENT_HOLD_OFF_TIME; 00448 break; 00449 case OpenCertificateChain: 00450 res_name_ptr = SECURITY_OPEN_CERTIFICATE_CHAIN; 00451 break; 00452 case CloseCertificateChain: 00453 res_name_ptr = SECURITY_CLOSE_CERTIFICATE_CHAIN; 00454 break; 00455 case ReadDeviceCertificateChain: 00456 res_name_ptr = SECURITY_READ_CERTIFICATE_CHAIN; 00457 break; 00458 } 00459 00460 if (res_name_ptr) { 00461 res_object = server_instance->resource(res_name_ptr); 00462 } 00463 } 00464 return res_object; 00465 } 00466 00467 void M2MSecurity::clear_resources(uint16_t instance_id) 00468 { 00469 for(int i = 0; i <= M2MSecurity::ClientHoldOffTime; i++) { 00470 M2MResource *res = get_resource((SecurityResource) i, instance_id); 00471 if (res) { 00472 res->clear_value(); 00473 } 00474 } 00475 } 00476 00477 int32_t M2MSecurity::get_security_instance_id(ServerType ser_type) const 00478 { 00479 int32_t instance_id = -1; 00480 00481 const M2MObjectInstanceList &insts = instances(); 00482 00483 if (!insts.empty()) { 00484 M2MObjectInstanceList::const_iterator it; 00485 it = insts.begin(); 00486 for ( ; it != insts.end(); it++ ) { 00487 uint16_t id = (*it)->instance_id(); 00488 if (server_type(id) == ser_type) { 00489 instance_id = id; 00490 break; 00491 } 00492 } 00493 } 00494 return instance_id; 00495 }
Generated on Mon Aug 29 2022 19:53:40 by
