Simulated product dispenser

Dependencies:   HTS221

Fork of mbed-cloud-workshop-connect-HTS221 by Jim Carver

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers m2msecurity.cpp Source File

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 }