From 330dfa58589f0f4bd8eaa80a7b7f56af33f6e9d3 Mon Sep 17 00:00:00 2001 From: Jung Seungho Date: Mon, 2 Jan 2017 17:09:24 +0900 Subject: [PATCH] modified cloud samples to work in tls mode - add TLS ciphersuites logic in samples - add libraries related to TLS ciphersuites in SConscript Change-Id: If1b7e95552deab984c4ac8f3432e31bd63dbd286 Signed-off-by: Jung Seungho Reviewed-on: https://gerrit.iotivity.org/gerrit/16039 Tested-by: jenkins-iotivity Reviewed-by: Jee Hyeok Kim Signed-off-by: Jee Hyeok Kim Reviewed-on: https://gerrit.iotivity.org/gerrit/16573 Tested-by: jenkins-iotivity --- cloud/samples/client/README | 8 +- cloud/samples/client/SConscript | 24 +- .../client/airconditioner/aircon_controlee.cpp | 99 +- .../client/airconditioner/aircon_controller.cpp | 105 +- cloud/samples/client/group_invite/group_invite.cpp | 1080 +++++++++++++++----- cloud/samples/client/messagequeue/mq_publisher.cpp | 113 +- .../samples/client/messagequeue/mq_subscriber.cpp | 117 ++- cloud/samples/client/rootca.crt | 21 + .../samples/client/thin_light/thin_room_light.cpp | 113 +- 9 files changed, 1353 insertions(+), 327 deletions(-) create mode 100644 cloud/samples/client/rootca.crt diff --git a/cloud/samples/client/README b/cloud/samples/client/README index fef9eed..f25c88e 100644 --- a/cloud/samples/client/README +++ b/cloud/samples/client/README @@ -1,10 +1,12 @@ To build cloud client samples, add WITH_TCP, TARGET_TRANSPORT=IP, WITH_CLOUD and WITH_MQ option to build command line -ex) scons WITH_TCP=yes TARGET_TRANSPORT=IP WITH_CLOUD=yes WITH_MQ=PUB,SUB +ex) scons WITH_TCP=yes TARGET_TRANSPORT=IP WITH_CLOUD=yes WITH_MQ=PUB,SUB SECURED=1 Cloud clients runs over CoAP over TCP transport. So you should declare WITH_TCP option. -Once you get samples which file name is 'aircon_controlee' and 'aircon_controller', you need 'Auth Code' to register resources on cloud with account scenario. +To run client samples io TLS mode, you should declare SECURED option to "1". + +Once you get samples (where the file names are 'aircon_controlee', 'aircon_controller', 'group_invite_sample', 'mq_publisher', 'mq_subscriber', and 'thin_room_light', you need 'Auth Code' to register resources on cloud with account scenario. Cloud stack has sample github and google oauth2 adaptor. @@ -21,4 +23,4 @@ http://www.example.com/oauth_callback/?code=bf9beb5db17ea476fa46 You can get 'Auth Code', value of '?code' query string. -The 'Auth Code' is one time token. So you need other token to run each sample. \ No newline at end of file +The 'Auth Code' is one time token. So you need other token to run each sample. diff --git a/cloud/samples/client/SConscript b/cloud/samples/client/SConscript index 61c91b7..32e8a1c 100644 --- a/cloud/samples/client/SConscript +++ b/cloud/samples/client/SConscript @@ -31,6 +31,11 @@ cc_sample_app_env = lib_env.Clone() ###################################################################### # Build flags ###################################################################### +# For bring up purposes only, the forked version will live here. +cc_sample_app_env.AppendUnique(CPPPATH = ['../../../resource/csdk/connectivity/lib/libcoap-4.1.1/include', + '../../../extlibs/mbedtls/mbedtls/include']) + + cc_sample_app_env.AppendUnique(CPPPATH = [ '../../../resource/include/', '../../../resource/csdk/resource-directory/include', @@ -38,19 +43,31 @@ cc_sample_app_env.AppendUnique(CPPPATH = [ '../../../resource/csdk/stack/include', '../../../resource/c_common/ocrandom/include', '../../../resource/csdk/logger/include', - '../../../resource/oc_logger/include' + '../../../resource/oc_logger/include', + '../../../resource/csdk/connectivity/inc', + '../../../resource/csdk/connectivity/api', + '../../../resource/csdk/connectivity/common/inc', + '../../../resource/csdk/security/provisioning/include', + '../../../resource/csdk/security/provisioning/include/internal' ]) cc_sample_app_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-Wextra', '-std=c++0x', '-pthread']) cc_sample_app_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')]) cc_sample_app_env.AppendUnique(RPATH = [env.get('BUILD_DIR')]) -cc_sample_app_env.PrependUnique(LIBS = ['oc', 'octbstack', 'pthread', 'resource_directory']) + +cc_sample_app_env.PrependUnique(LIBS = ['oc', 'octbstack','connectivity_abstraction','pthread', 'resource_directory', 'ocpmapi']) cc_sample_app_env.AppendUnique(CPPDEFINES = ['WITH_CLOUD', 'RD_CLIENT']) ###################################################################### -# Source files and Targets +# Install for rootca certificate ###################################################################### +src_dir = cc_sample_app_env.get('SRC_DIR') +cc_cloud_src_dir = src_dir + '/cloud/samples/client/' + +tlsOption = env.get('SECURED') +if tlsOption is '1': + cc_sample_app_env.Install('.', cc_cloud_src_dir + 'rootca.crt') ###################################################################### # Sample for the thin cloud device @@ -73,7 +90,6 @@ aircon_controller_src = [ ] cc_sample_app_env.Program('aircon_controller', aircon_controller_src) - ###################################################################### # Samples for message queue ###################################################################### diff --git a/cloud/samples/client/airconditioner/aircon_controlee.cpp b/cloud/samples/client/airconditioner/aircon_controlee.cpp index e5d33af..5018988 100644 --- a/cloud/samples/client/airconditioner/aircon_controlee.cpp +++ b/cloud/samples/client/airconditioner/aircon_controlee.cpp @@ -14,9 +14,17 @@ #include #include +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) +#include "ocprovisioningmanager.h" +#include "mbedtls/ssl_ciphersuites.h" +#include +#endif // WITH_DTLS__ or __WITH_TLS__ + using namespace OC; using namespace std; +string g_host; + class Resource { public: @@ -495,6 +503,51 @@ void handleLoginoutCB(const HeaderOptions &, g_callbackLock.notify_all(); } +int saveTrustCert(void) +{ + OCStackResult res = OC_STACK_ERROR; + uint16_t g_credId = 0; + + cout << "Save Trust Cert. Chain into Cred of SVR" < 0) + { + trustCertChainArray.data = (uint8_t *)malloc(fsize); + trustCertChainArray.len = fsize; + if (NULL == trustCertChainArray.data) + { + cout << "Failed to allocate memory" << endl; + fclose(fp); + return res; + } + rewind(fp); + if (fsize != fread(trustCertChainArray.data, 1, fsize, fp)) + { + cout << "Certiface not read completely" << endl; + } + fclose(fp); + } + } + + res = OCSaveTrustCertChain(trustCertChainArray.data, trustCertChainArray.len, OIC_ENCODING_PEM,&g_credId); + + if(OC_STACK_OK != res) + { + cout << "OCSaveTrustCertChainBin API error" << endl; + return res; + } + cout << "CredId of Saved Trust Cert. Chain into Cred of SVR : " << g_credId << endl; + + return res; +} + static FILE *client_open(const char *path, const char *mode) { if (0 == strcmp(path, OC_SECURITY_DB_DAT_FILE_NAME)) @@ -549,11 +602,11 @@ OCStackResult SetDeviceInfo() int main(int argc, char *argv[]) { - if (argc != 4 && argc != 5) + if (argc != 5) { - cout << "Put \"[host-ipaddress:port] [authprovider] [authcode]\" for sign-up and sign-in and publish resources" + cout << "Put \"[host-ipaddress:port] [authprovider] [authcode] [tls mode(0,1)]\" for sign-up and sign-in and publish resources" << endl; - cout << "Put \"[host-ipaddress:port] [uid] [accessToken] 1\" for sign-in and publish resources" << + cout << "Put \"[host-ipaddress:port] [uid] [accessToken] [tls mode(0,1)]\" for sign-in and publish resources" << endl; return 0; } @@ -574,16 +627,41 @@ int main(int argc, char *argv[]) OCStackResult result = OC_STACK_ERROR; - string host = "coap+tcp://"; - host += argv[1]; - - OCAccountManager::Ptr accountMgr = OCPlatform::constructAccountManagerObject(host, + g_host = "coap+tcp://"; + + if (!strcmp(argv[4],"1")) + { +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) + g_host = "coaps+tcp://"; +#endif + } + + g_host += argv[1]; + + OCAccountManager::Ptr accountMgr = OCPlatform::constructAccountManagerObject(g_host, CT_ADAPTER_TCP); + if (!strcmp(argv[4], "1")) + { +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) + cout << "Security Mode" << endl; + if (CA_STATUS_OK != saveTrustCert()) + { + cout << "saveTrustCert returned an error" << endl; + } + + uint16_t cipher = MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256; + if (CA_STATUS_OK != CASelectCipherSuite(cipher, CA_ADAPTER_TCP)) + { + cout << "CASelectCipherSuite returned an error" << endl; + } +#endif + } + mutex blocker; unique_lock lock(blocker); - if (argc == 5) + if (strlen(argv[2]) > 35) { accountMgr->signIn(argv[2], argv[3], &handleLoginoutCB); g_callbackLock.wait(lock); @@ -596,7 +674,6 @@ int main(int argc, char *argv[]) g_callbackLock.wait(lock); } - cout << "Registering resources to platform..." << endl; AirConditionerResource airConditioner("/sec/aircon/0", { "x.com.samsung.da.device" }, { DEFAULT_INTERFACE, BATCH_INTERFACE, LINK_INTERFACE }); @@ -700,7 +777,7 @@ int main(int argc, char *argv[]) ResourceHandles resourceHandles; - result = RDClient::Instance().publishResourceToRD(host, OCConnectivityType::CT_ADAPTER_TCP, + result = RDClient::Instance().publishResourceToRD(g_host, OCConnectivityType::CT_ADAPTER_TCP, resourceHandles, &onPublish); @@ -708,7 +785,7 @@ int main(int argc, char *argv[]) resourceHandles.push_back(airConditioner.m_handle); - result = RDClient::Instance().publishResourceToRD(host, OCConnectivityType::CT_ADAPTER_TCP, + result = RDClient::Instance().publishResourceToRD(g_host, OCConnectivityType::CT_ADAPTER_TCP, resourceHandles, &onPublish); diff --git a/cloud/samples/client/airconditioner/aircon_controller.cpp b/cloud/samples/client/airconditioner/aircon_controller.cpp index e5e43b4..0f2c2e3 100644 --- a/cloud/samples/client/airconditioner/aircon_controller.cpp +++ b/cloud/samples/client/airconditioner/aircon_controller.cpp @@ -13,6 +13,12 @@ #include #include +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) +#include "ocprovisioningmanager.h" +#include "mbedtls/ssl_ciphersuites.h" +#include +#endif // WITH_DTLS__ or __WITH_TLS__ + using namespace OC; using namespace std; @@ -267,6 +273,51 @@ void presenceDevice(OCStackResult , const unsigned int i, const string &str) cout << "Presence received, i=" << i << " str=" << str << endl; } +int saveTrustCert(void) +{ + OCStackResult res = OC_STACK_ERROR; + uint16_t g_credId = 0; + + cout << "Save Trust Cert. Chain into Cred of SVR" < 0) + { + trustCertChainArray.data = (uint8_t *)malloc(fsize); + trustCertChainArray.len = fsize; + if (NULL == trustCertChainArray.data) + { + cout << "Failed to allocate memory" << endl; + fclose(fp); + return res; + } + rewind(fp); + if (fsize != fread(trustCertChainArray.data, 1, fsize, fp)) + { + cout << "Certiface not read completely" << endl; + } + fclose(fp); + } + } + + res = OCSaveTrustCertChain(trustCertChainArray.data, trustCertChainArray.len, OIC_ENCODING_PEM,&g_credId); + + if(OC_STACK_OK != res) + { + cout << "OCSaveTrustCertChainBin API error" << endl; + return res; + } + cout << "CredId of Saved Trust Cert. Chain into Cred of SVR : " << g_credId << endl; + + return res; +} + static FILE *client_open(const char *path, const char *mode) { if (0 == strcmp(path, OC_SECURITY_DB_DAT_FILE_NAME)) @@ -281,14 +332,14 @@ static FILE *client_open(const char *path, const char *mode) int main(int argc, char *argv[]) { - if (argc != 4 && argc != 5) - { - cout << "Put \"[host-ipaddress:port] [authprovider] [authcode]\" for sign-up and sign-in and discover resources" - << endl; - cout << "Put \"[host-ipaddress:port] [uid] [accessToken] 1\" for sign-in and discover resources" << - endl; - return 0; - } + if (argc != 5) + { + cout << "Put \"[host-ipaddress:port] [authprovider] [authcode] [tls mode(0,1)]\" for sign-up and sign-in and publish resources" + << endl; + cout << "Put \"[host-ipaddress:port] [uid] [accessToken] [tls mode(0,1)]\" for sign-in and publish resources" << + endl; + return 0; + } OCPersistentStorage ps{ client_open, fread, fwrite, fclose, unlink }; @@ -306,18 +357,42 @@ int main(int argc, char *argv[]) OCStackResult result = OC_STACK_ERROR; - g_host = "coap+tcp://"; + g_host = "coap+tcp://"; + + if (!strcmp(argv[4], "1")) + { +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) + g_host = "coaps+tcp://"; +#endif + } + g_host += argv[1]; OCAccountManager::Ptr accountMgr = OCPlatform::constructAccountManagerObject(g_host, CT_ADAPTER_TCP); - - mutex blocker; - unique_lock lock(blocker); - - if (argc == 5) - { + if (!strcmp(argv[4], "1")) + { +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) + cout << "Security Mode" << endl; + if (CA_STATUS_OK != saveTrustCert()) + { + cout << "saveTrustCert returned an error" << endl; + } + + uint16_t cipher = MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256; + if (CA_STATUS_OK != CASelectCipherSuite(cipher, CA_ADAPTER_TCP)) + { + cout << "CASelectCipherSuite returned an error" << endl; + } +#endif + } + + mutex blocker; + unique_lock lock(blocker); + + if (strlen(argv[2]) > 35) + { accountMgr->signIn(argv[2], argv[3], &handleLoginoutCB); g_callbackLock.wait(lock); } diff --git a/cloud/samples/client/group_invite/group_invite.cpp b/cloud/samples/client/group_invite/group_invite.cpp index e4b8873..51cd225 100644 --- a/cloud/samples/client/group_invite/group_invite.cpp +++ b/cloud/samples/client/group_invite/group_invite.cpp @@ -1,42 +1,269 @@ /* **************************************************************** -* -* Copyright 2016 Samsung Electronics All Rights Reserved. -* -* -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -* -******************************************************************/ - -#include -#include -#include + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +#include "OCPlatform.h" +#include "OCApi.h" +#include "RDClient.h" #include -#include -#include -#include -#include -#include -#include "ocstack.h" -#include "ocpayload.h" - -#include -#include +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) +#include "ocprovisioningmanager.h" +#include "mbedtls/ssl_ciphersuites.h" +#include +#endif // WITH_DTLS__ or __WITH_TLS__ using namespace std; using namespace OC; +string g_host; +condition_variable g_callbackLock; +string g_accesstoken, g_refreshtoken, g_tokentype, g_uid, g_redirectUri, g_certificate, g_serverId; +int g_expiresin; + +class Resource +{ + public: + OCResourceHandle m_handle; + Resource(string uri, vector< string > rt, vector< string > itf) + { + m_representation.setUri(uri); + m_representation.setResourceTypes(rt); + m_representation.setResourceInterfaces(itf); + } + + string getResourceUri() + { + return m_representation.getUri(); + } + + vector< string > getResourceType() + { + return m_representation.getResourceTypes(); + } + + vector< string > getInterfaces() + { + return m_representation.getResourceInterfaces(); + } + + OCRepresentation getRepresentation(void) + { + m_representation.clearChildren(); + for (auto it = m_childResources.begin(); it != m_childResources.end(); it++) + { + m_representation.addChild((*it)->getRepresentation()); + } + return m_representation; + } + + OCStackResult addChildResource(Resource *childResource) + { + m_childResources.push_back(childResource); + return OCPlatform::bindResource(m_handle, childResource->m_handle); + } + + OCStackResult sendRepresentation(shared_ptr< OCResourceRequest > pRequest) + { + auto pResponse = make_shared< OC::OCResourceResponse >(); + pResponse->setRequestHandle(pRequest->getRequestHandle()); + pResponse->setResourceHandle(pRequest->getResourceHandle()); + + // Check for query params (if any) + QueryParamsMap queryParamsMap = pRequest->getQueryParameters(); + + cout << "\t\t\tquery params: \n"; + for (auto it = queryParamsMap.begin(); it != queryParamsMap.end(); it++) + { + cout << "\t\t\t\t" << it->first << ":" << it->second << endl; + } + + auto findRes = queryParamsMap.find("if"); + + if (findRes != queryParamsMap.end()) + { + pResponse->setResourceRepresentation(getRepresentation(), findRes->second); + } + else + { + pResponse->setResourceRepresentation(getRepresentation(), DEFAULT_INTERFACE); + } + + pResponse->setResponseResult(OC_EH_OK); + + return OCPlatform::sendResponse(pResponse); + } + + OCStackResult propagate() + { + if (m_interestedObservers.size() > 0) + { + shared_ptr resourceResponse = + { make_shared()}; + + resourceResponse->setResourceRepresentation(getRepresentation(), DEFAULT_INTERFACE); + + return OCPlatform::notifyListOfObservers(m_handle, + m_interestedObservers, + resourceResponse); + } + + return OC_STACK_OK; + } + + virtual OCEntityHandlerResult entityHandler(shared_ptr request) = 0; + + protected: + OCRepresentation m_representation; + vector m_childResources; + ObservationIds m_interestedObservers; +}; + +class BinarySwitchResource: public Resource //oic.r.switch.binary +{ + private: + bool m_value; + + public: + BinarySwitchResource(string uri, vector< string > rt, vector< string > itf) : + Resource(uri, rt, itf) + { + m_value = false; + m_representation.setValue("value", m_value); + } + + void setBinarySwitchRepresentation(OCRepresentation &rep) + { + bool value; + if (rep.getValue("value", value)) + { + m_value = value; + m_representation.setValue("value", m_value); + cout << "\t\t\t\t" << "value: " << m_value << endl; + + propagate(); + } + } + + OCEntityHandlerResult entityHandler(shared_ptr< OCResourceRequest > request) + { + cout << "\tIn Server Binaryswitch entity handler:\n"; + OCEntityHandlerResult ehResult = OC_EH_ERROR; + + if (request) + { + // Get the request type and request flag + string requestType = request->getRequestType(); + int requestFlag = request->getRequestHandlerFlag(); + + if (requestFlag & RequestHandlerFlag::RequestFlag) + { + cout << "\t\trequestFlag : Request\n"; + + // If the request type is GET + if (requestType == "GET") + { + cout << "\t\t\trequestType : GET\n"; + if (OC_STACK_OK == sendRepresentation(request)) + { + ehResult = OC_EH_OK; + } + } + else if (requestType == "PUT") + { + cout << "\t\t\trequestType : PUT\n"; + // PUT request operations + } + else if (requestType == "POST") + { + cout << "\t\t\trequestType : POST\n"; + // POST request operations + OCRepresentation rep = request->getResourceRepresentation(); + setBinarySwitchRepresentation(rep); + + if (OC_STACK_OK == sendRepresentation(request)) + { + ehResult = OC_EH_OK; + } + } + else if (requestType == "DELETE") + { + cout << "\t\t\trequestType : DELETE\n"; + // DELETE request operations + } + } + + if (requestFlag & RequestHandlerFlag::ObserverFlag) + { + cout << "\t\trequestFlag : Observer\n"; + + ObservationInfo observationInfo = request->getObservationInfo(); + if (ObserveAction::ObserveRegister == observationInfo.action) + { + m_interestedObservers.push_back(observationInfo.obsId); + } + else if (ObserveAction::ObserveUnregister == observationInfo.action) + { + m_interestedObservers.erase( + remove(m_interestedObservers.begin(), m_interestedObservers.end(), + observationInfo.obsId), m_interestedObservers.end()); + } + } + } + else + { + cout << "Request invalid" << endl; + } + + return ehResult; + } +}; + +OCAccountManager::Ptr accountMgr; + +void printUsage() +{ + cout << endl << "---Group & Invite sample---" << endl; + cout << " 1 - searchUser using user UUID" << endl; + cout << " 2 - searchUser using email" << endl; + cout << " 3 - searchUser using phone" << endl; + cout << " 4 - deleteDevice" << endl; + cout << " 5 - observeGroup" << endl; + cout << " 6 - createGroup" << endl; + cout << " 7 - deleteGroup" << endl; + cout << " 8 - getGroupInfoAll" << endl; + cout << " 9 - getGroupInfo" << endl; + cout << " 10 - addPropertyValueToGroup" << endl; + cout << " 11 - deletePropertyValueFromGroup" << endl; + cout << " 12 - updatePropertyValueOnGroup" << endl; + cout << " 13 - observeInvitation" << endl; + cout << " 14 - sendInvitation" << endl; + cout << " 15 - cancelInvitation" << endl; + cout << " 16 - deleteInvitation" << endl; + cout << " 17 - cancelObserveGroup" << endl; + cout << " 18 - cancelObserveInvitation" << endl; + cout << " 30 - resource discover" << endl; + cout << " 31 - example resource publish" << endl; + cout << " 41 - get my info (device Id, accesstoken, user uuid)" << endl; + cout << " 50 - exit" << endl; +} + void printRepresentation(OCRepresentation rep) { for (auto itr = rep.begin(); itr != rep.end(); ++itr) @@ -47,21 +274,21 @@ void printRepresentation(OCRepresentation rep) switch (itr->base_type()) { case AttributeType::OCRepresentation: - for (auto itr2 : (*itr).getValue >()) + for (auto itr2 : (*itr).getValue< vector< OCRepresentation > >()) { printRepresentation(itr2); } break; case AttributeType::Integer: - for (auto itr2 : (*itr).getValue >()) + for (auto itr2 : (*itr).getValue< vector< int > >()) { cout << "\t\t" << itr2 << endl; } break; case AttributeType::String: - for (auto itr2 : (*itr).getValue >()) + for (auto itr2 : (*itr).getValue< vector< string > >()) { cout << "\t\t" << itr2 << endl; } @@ -74,14 +301,13 @@ void printRepresentation(OCRepresentation rep) } else if (itr->type() == AttributeType::OCRepresentation) { - printRepresentation((*itr).getValue()); + printRepresentation((*itr).getValue< OCRepresentation >()); } } } //tmp callback -void ocPost(const HeaderOptions & /*headerOptions*/, - const OCRepresentation &rep, const int eCode) +void onPost(const HeaderOptions & /*headerOptions*/, const OCRepresentation &rep, const int eCode) { if (eCode == OC_STACK_OK || eCode == OC_STACK_RESOURCE_CHANGED) { @@ -93,10 +319,11 @@ void ocPost(const HeaderOptions & /*headerOptions*/, { cout << "\tResponse error: " << eCode << endl; } + printUsage(); } -void onObserve(const HeaderOptions /*headerOptions*/, const OCRepresentation &rep, - const int &eCode, const int &sequenceNumber) +void onObserve(const HeaderOptions /*headerOptions*/, const OCRepresentation &rep, const int &eCode, + const int &sequenceNumber) { try { @@ -114,7 +341,8 @@ void onObserve(const HeaderOptions /*headerOptions*/, const OCRepresentation &re { if (eCode == OC_STACK_OK) { - cout << "Observe registration failed or de-registration action failed/succeeded" << endl; + cout << "Observe registration failed or de-registration action failed/succeeded" + << endl; } else { @@ -127,10 +355,99 @@ void onObserve(const HeaderOptions /*headerOptions*/, const OCRepresentation &re { cout << "Exception: " << e.what() << " in onObserve" << endl; } + printUsage(); +} + +void onPublish(const OCRepresentation &, const int &eCode) +{ + cout << "Publish resource response received, code: " << eCode << endl; + + g_callbackLock.notify_all(); + printUsage(); +} + +shared_ptr< OCResource > g_Resource; + +void onFoundResource(shared_ptr< OCResource > resource) +{ + cout << "In foundResource\n"; + string resourceURI; + string hostAddress; + + try + { + // Do some operations with resource object. + if (resource) + { + g_Resource = resource; + cout << "DISCOVERED Resource:" << endl; + // Get the resource URI + resourceURI = resource->uri(); + cout << "\tURI of the resource: " << resourceURI << endl; + + // Get the resource host address + hostAddress = resource->host(); + cout << "\tHost address of the resource: " << hostAddress << endl; + + // Get the resource types + cout << "\tList of resource types: " << endl; + for (auto &resourceTypes : resource->getResourceTypes()) + { + cout << "\t\t" << resourceTypes << endl; + } + + // Get the resource interfaces + cout << "\tList of resource interfaces: " << endl; + for (auto &resourceInterfaces : resource->getResourceInterfaces()) + { + cout << "\t\t" << resourceInterfaces << endl; + } + } + else + { + // Resource is invalid + cout << "Resource is invalid" << endl; + } + + } + catch (exception &e) + { + cerr << "Exception in foundResource: " << e.what() << endl; + } +} + +void printResource(const OCRepresentation &rep) +{ + cout << "URI: " << rep.getUri() << endl; + + vector< string > rt = rep.getResourceTypes(); + for (auto it = rt.begin(); it != rt.end(); it++) + { + cout << "RT: " << (*it) << endl; + } + + for (auto it = rep.begin(); it != rep.end(); it++) + { + cout << it->attrname() << " : " << it->getValueToString() << endl; + } + + vector< OCRepresentation > children = rep.getChildren(); + + for (auto it = children.begin(); it != children.end(); it++) + { + printResource(*it); + } + printUsage(); +} + +void getCollectionResource(const HeaderOptions &, const OCRepresentation &rep, const int ecode) +{ + cout << "Resource get: " << ecode << endl; + + printResource(rep); } -void onDelete(const HeaderOptions & /*headerOptions*/, - const int eCode) +void onDelete(const HeaderOptions & /*headerOptions*/, const int eCode) { if (eCode == OC_STACK_OK || eCode == OC_STACK_RESOURCE_DELETED) { @@ -140,14 +457,49 @@ void onDelete(const HeaderOptions & /*headerOptions*/, { cout << "\tDelete Response error: " << eCode << endl; } + printUsage(); } -condition_variable g_callbackLock; -string g_uid; -string g_accesstoken; +void onSignUp(const HeaderOptions & /*headerOptions*/, const OCRepresentation &rep, const int eCode) +{ + if (eCode == OC_STACK_OK || eCode == OC_STACK_RESOURCE_CHANGED) + { + cout << "\tSign-up request was successful" << endl; + + printRepresentation(rep); + + // Mandatory field + g_accesstoken = rep.getValue < string > ("accesstoken"); + g_refreshtoken = rep.getValue < string > ("refreshtoken"); + g_tokentype = rep.getValue < string > ("tokentype"); + g_uid = rep.getValue < string > ("uid"); + + // Optional field + if (rep.hasAttribute("expiresin")) + { + g_expiresin = rep.getValue< int >("expiresin"); + } + if (rep.hasAttribute("redirecturi")) + { + g_redirectUri = rep.getValue < string > ("redirecturi"); + } + if (rep.hasAttribute("certificate")) + { + g_certificate = rep.getValue < string > ("certificate"); + } + if (rep.hasAttribute("sid")) + { + g_serverId = rep.getValue < string > ("sid"); + } + } + else + { + cout << "\tSign-up Response error: " << eCode << endl; + } + g_callbackLock.notify_all(); +} -void handleLoginoutCB(const HeaderOptions &, - const OCRepresentation &rep, const int ecode) +void handleLoginoutCB(const HeaderOptions &, const OCRepresentation &rep, const int ecode) { cout << "Auth response received code: " << ecode << endl; @@ -156,288 +508,525 @@ void handleLoginoutCB(const HeaderOptions &, printRepresentation(rep); } - if (ecode == 4) + g_callbackLock.notify_all(); +} + +int insertNumber() +{ + int var; + while (1) + { + cin >> var; + if (cin.fail() == 1) + { + cin.clear(); + cin.ignore(100, '\n'); + } + else + { + return var; + } + } +} + +int saveTrustCert(void) +{ + OCStackResult res = OC_STACK_ERROR; + uint16_t g_credId = 0; + + cout << "Save Trust Cert. Chain into Cred of SVR" << endl; + + ByteArray trustCertChainArray = {0, 0}; + + FILE *fp = fopen("rootca.crt", "rb+"); + + if (fp) { - g_accesstoken = rep.getValueToString("accesstoken"); + size_t fsize; + if (fseeko(fp, 0, SEEK_END) == 0 && (fsize = ftello(fp)) > 0) + { + trustCertChainArray.data = (uint8_t *)malloc(fsize); + trustCertChainArray.len = fsize; + if (NULL == trustCertChainArray.data) + { + cout << "Failed to allocate memory" << endl; + fclose(fp); + return res; + } + rewind(fp); + if (fsize != fread(trustCertChainArray.data, 1, fsize, fp)) + { + cout << "Certiface not read completely" << endl; + } + fclose(fp); + } + } + + res = OCSaveTrustCertChain(trustCertChainArray.data, trustCertChainArray.len, OIC_ENCODING_PEM, + &g_credId); - g_uid = rep.getValueToString("uid"); + if (OC_STACK_OK != res) + { + cout << "OCSaveTrustCertChainBin API error" << endl; + return res; } + cout << "CredId of Saved Trust Cert. Chain into Cred of SVR : " << g_credId << endl; - g_callbackLock.notify_all(); + return res; +} + +static FILE *client_open(const char * /*path*/, const char *mode) +{ + return fopen("./rootca.dat", mode); } int main(int argc, char *argv[]) { - if (argc != 4 && argc != 5) + if (argc != 5) { - cout << "Put \"[host-ipaddress:port] [authprovider] [authcode]\" for sign-up and sign-in" + cout << "Put \"[host-ipaddress:port] [authprovider] [authcode] [tls mode(0,1)]\" for sign-up and sign-in and publish resources" << endl; - cout << "Put \"[host-ipaddress:port] [uid] [accessToken] 1\" for sign-in" << + cout << "Put \"[host-ipaddress:port] [uid] [accessToken] [tls mode(0,1)]\" for sign-in and publish resources" + << endl; return 0; } + OCPersistentStorage ps{ client_open, fread, fwrite, fclose, unlink }; + PlatformConfig cfg { ServiceType::InProc, ModeType::Both, "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces - 0, // Uses randomly available port - QualityOfService::LowQos + 0, // Uses randomly available port + QualityOfService::LowQos, + &ps }; - OCPlatform::Configure(cfg); - OCStackResult result = OC_STACK_ERROR; - string host = "coap+tcp://"; - host += argv[1]; + g_host = "coap+tcp://"; + + if (!strcmp(argv[4], "1")) + { +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) + g_host = "coaps+tcp://"; +#endif + } + + g_host += argv[1]; - OCAccountManager::Ptr accountMgr = OCPlatform::constructAccountManagerObject(host, - CT_ADAPTER_TCP); + accountMgr = OCPlatform::constructAccountManagerObject(g_host, CT_ADAPTER_TCP); + + if (!strcmp(argv[4], "1")) + { +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) + cout << "Security Mode" << endl; + if (CA_STATUS_OK != saveTrustCert()) + { + cout << "saveTrustCert returned an error" << endl; + } + + uint16_t cipher = MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256; + if (CA_STATUS_OK != CASelectCipherSuite(cipher, CA_ADAPTER_TCP)) + { + cout << "CASelectCipherSuite returned an error" << endl; + } +#endif + } mutex blocker; unique_lock lock(blocker); - if (argc == 5) + if (strlen(argv[2]) > 35) { accountMgr->signIn(argv[2], argv[3], &handleLoginoutCB); g_callbackLock.wait(lock); } else { - accountMgr->signUp(argv[2], argv[3], &handleLoginoutCB); + accountMgr->signUp(argv[2], argv[3], &onSignUp); g_callbackLock.wait(lock); accountMgr->signIn(g_uid, g_accesstoken, &handleLoginoutCB); g_callbackLock.wait(lock); } - cout << "---Group & Invite sample---" << endl; - cout << " 1 - searchUser using user UUID" << endl; - cout << " 2 - searchUser using email" << endl; - cout << " 3 - searchUser using phone" << endl; - cout << " 4 - deleteDevice" << endl; - cout << " 5 - observeGroup" << endl; - cout << " 6 - createGroup" << endl; - cout << " 7 - deleteGroup" << endl; - cout << " 8 - getGroupInfoAll" << endl; - cout << " 9 - getGroupInfo" << endl; - cout << " 10 - addPropertyValueToGroup" << endl; - cout << " 11 - deletePropertyValueFromGroup" << endl; - cout << " 12 - updatePropertyValueOnGroup" << endl; - cout << " 13 - observeInvitation" << endl; - cout << " 14 - sendInvitation" << endl; - cout << " 15 - cancelInvitation" << endl; - cout << " 16 - deleteInvitation" << endl; - cout << " 17 - cancelObserveGroup" << endl; - cout << " 18 - cancelObserveInvitation" << endl; - cout << " 20 - exit" << endl; + cout << "Registering resources to platform..." << endl; + + BinarySwitchResource binarySwitch("/power/0", + { "oic.r.switch.binary" }, + { DEFAULT_INTERFACE }); + + printUsage(); string cmd; + int intCmd; string cmd2; + string uri; + string itf; + string rt; while (true) { - cin >> cmd; - + intCmd = insertNumber(); try { QueryParamsMap query; OCRepresentation rep; - switch (atoi(cmd.c_str())) - { - case 1: - cout << "Put userUUID to search:" << endl; - cin >> cmd; - query["uid"] = cmd; - result = accountMgr->searchUser(query, &ocPost); - break; - - case 2: - cout << "Put email to search:" << endl; - cin >> cmd; - query["email"] = cmd; - result = accountMgr->searchUser(query, &ocPost); - break; - - case 3: - cout << "Put phone number to search:" << endl; - cin >> cmd; - query["phone"] = cmd; - result = accountMgr->searchUser(query, &ocPost); - break; - - case 4: + switch (intCmd) { - string accessToken, deviceId; + case 1: + cout << "Put userUUID to search:" << endl; + cin >> cmd; + query["uid"] = cmd; + result = accountMgr->searchUser(query, &onPost); + break; - cout << "PUT accessToken:"; - cin >> accessToken; + case 2: + cout << "Put email to search:" << endl; + cin >> cmd; + query["email"] = cmd; + result = accountMgr->searchUser(query, &onPost); + break; - cout << "PUT deviceID to delete:"; - cin >> deviceId; + case 3: + cout << "Put phone number to search:" << endl; + cin >> cmd; + query["phone"] = cmd; + result = accountMgr->searchUser(query, &onPost); + break; - result = accountMgr->deleteDevice(accessToken, deviceId, &onDelete); - break; - } + case 4: + { + string accessToken, deviceId; - case 5: - result = accountMgr->observeGroup(&onObserve); - break; + cout << "PUT accessToken:"; + cin >> accessToken; - case 6: - result = accountMgr->createGroup(&ocPost); - break; + cout << "PUT deviceID to delete:"; + cin >> deviceId; - case 7: - cout << "PUT groupId to delete:"; - cin >> cmd; - result = accountMgr->deleteGroup(cmd, &onDelete); - break; + result = accountMgr->deleteDevice(accessToken, deviceId, &onDelete); + break; + } - case 8: - result = accountMgr->getGroupInfoAll(&ocPost); - break; + case 5: + result = accountMgr->observeGroup(&onObserve); + break; - case 9: - cout << "PUT groupId to get info:"; - cin >> cmd; - result = accountMgr->getGroupInfo(cmd, &ocPost); - break; + case 6: + { + int opt; + cout + << "\n---------------------------------------------------------------------\n"; + cout << " w/ optional field? (1:yes / 2:no)" << endl; + cout + << "---------------------------------------------------------------------\n\n"; + cin >> opt; + + if (opt == 1) + { + QueryParamsMap queryParam = + { }; + string key, value; + + int n; + cout << "\nnum of field : "; + n = insertNumber(); + + for (int i = 0; i < n; i++) + { + cout << "query key(ex: gname/parent): "; + cin >> key; + cout << "query value: "; + cin >> value; + queryParam.insert(pair< string, string >(key, value)); + } + result = accountMgr->createGroup(queryParam, &onPost); + } + else if (opt == 2) + { + result = accountMgr->createGroup(&onPost); + } + else + { + cout << "invalid option" << endl; + } + + break; + } + case 7: + cout << "PUT groupId to delete:"; + cin >> cmd; + result = accountMgr->deleteGroup(cmd, &onDelete); + break; - case 10: - { - string groupId, property, value; - vector values; - OCRepresentation propertyValue; + case 8: + result = accountMgr->getGroupInfoAll(&onPost); + break; - cout << "PUT groupId to add property values:"; - cin >> groupId; + case 9: + cout << "PUT groupId to get info:"; + cin >> cmd; + result = accountMgr->getGroupInfo(cmd, &onPost); + break; - cout << "PUT property name:"; - cin >> property; + case 10: + { + string groupId; + cout << "group ID: "; + cin >> groupId; - cout << "PUT value:"; - cin >> value; + int n; + cout << "num of property : "; + n = insertNumber(); - values.push_back(value); - propertyValue.setValue>(property, values); + OCRepresentation propertyValue; - accountMgr->addPropertyValueToGroup(groupId, propertyValue, &ocPost); - break; - } + for (int i = 0; i < n; i++) + { + string key, value; + vector< string > values; - case 11: - { - string groupId, property, value; - vector values; - OCRepresentation propertyValue; + cout << "property(ex: members/devices): "; + cin >> key; - cout << "PUT groupId to delete property values:"; - cin >> groupId; + int m; + cout << "\tnum of values : "; + m = insertNumber(); - cout << "PUT property name:"; - cin >> property; + for (int j = 0; j < m; j++) + { + cout << "\tvalue: "; + cin >> value; + values.push_back(value); + } - cout << "PUT value:"; - cin >> value; + propertyValue.setValue < vector < string >> (key, values); + } - values.push_back(value); - propertyValue.setValue>(property, values); + result = accountMgr->addPropertyValueToGroup(groupId, propertyValue, &onPost); + break; + } - accountMgr->deletePropertyValueFromGroup(groupId, propertyValue, &ocPost); - break; - } + case 11: + { + string groupId; + cout << "group ID: "; + cin >> groupId; - case 12: - { - string groupId, property, value; - OCRepresentation propertyValue; + int n; + cout << "number of properties : "; + n = insertNumber(); - cout << "PUT groupId to update property values:"; - cin >> groupId; + OCRepresentation propertyValue; - cout << "PUT property name:"; - cin >> property; + for (int i = 0; i < n; i++) + { + string key, value; + vector< string > values; - int type; - cout << "PUT value type(1:string / 2:array):"; - cin >> type; + cout << "property(ex: members/devices): "; + cin >> key; - cout << "PUT value:"; - cin >> value; + int m; + cout << "\tnum of values : "; + m = insertNumber(); - if (1 == type) - { - propertyValue.setValue(property, value); - } - else if (2 == type) - { - vector values; - values.push_back(value); - propertyValue.setValue>(property, values); - } - else - { + for (int j = 0; j < m; j++) + { + cout << "\tvalue: "; + cin >> value; + values.push_back(value); + } + + propertyValue.setValue < vector < string >> (key, values); + } + + result = accountMgr->deletePropertyValueFromGroup(groupId, propertyValue, + &onPost); + } + + case 12: + { + string groupId; + cout << "group ID: "; + cin >> groupId; + + int n; + cout << "num of property : "; + n = insertNumber(); + + OCRepresentation propertyValue; + + for (int i = 0; i < n; i++) + { + string key, value; + + cout << "property(ex: gname/devices): "; + cin >> key; + + int opt; + cout << "\tvalue type?(1:string / 2:array) : "; + opt = insertNumber(); + + if (opt == 1) + { + cout << "\tvalue: "; + cin >> value; + propertyValue.setValue < string > (key, value); + } + else if (opt == 2) + { + vector< string > values; + + int m; + cout << "\tnum of values : "; + m = insertNumber(); + + for (int j = 0; j < m; j++) + { + cout << "\tvalue: "; + cin >> value; + values.push_back(value); + } + + propertyValue.setValue < vector < string >> (key, values); + } + else + { + cout << "invalid option" << endl; + break; + } + } + + result = accountMgr->updatePropertyValueOnGroup(groupId, propertyValue, + &onPost); + break; + } + case 13: + result = accountMgr->observeInvitation(&onObserve); break; - } - accountMgr->updatePropertyValueOnGroup(groupId, propertyValue, &ocPost); - break; - } + case 14: + cout << "PUT groupId to invite:"; + cin >> cmd; + cout << "PUT userUUID to invite:"; + cin >> cmd2; + result = accountMgr->sendInvitation(cmd, cmd2, &onPost); + break; - case 13: - result = accountMgr->observeInvitation(&onObserve); - break; - - case 14: - cout << "PUT groupId to invite:"; - cin >> cmd; - cout << "PUT userUUID to invite:"; - cin >> cmd2; - result = accountMgr->sendInvitation(cmd, cmd2, &ocPost); - break; - - case 15: - cout << "PUT groupId to cancel invitation:"; - cin >> cmd; - cout << "PUT userUUID to cancel invitation:"; - cin >> cmd2; - result = accountMgr->cancelInvitation(cmd, cmd2, &onDelete); - break; - - case 16: - cout << "PUT groupId to reply to invitation:"; - cin >> cmd; - cout << "accept to invitation? (1:yes)"; - cin >> cmd2; - - if (cmd2 == "1") - { - result = accountMgr->replyToInvitation(cmd, true, &onDelete); - } - else - { - result = accountMgr->replyToInvitation(cmd, false, &onDelete); - } - break; + case 15: + cout << "PUT groupId to cancel invitation:"; + cin >> cmd; + cout << "PUT userUUID to cancel invitation:"; + cin >> cmd2; + result = accountMgr->cancelInvitation(cmd, cmd2, &onDelete); + break; - case 17: - result = accountMgr->cancelObserveGroup(); - break; + case 16: + cout << "PUT groupId to reply to invitation:"; + cin >> cmd; + cout << "accept to invitation? (1:yes)"; + cin >> cmd2; - case 18: - result = accountMgr->cancelObserveInvitation(); - break; + if (cmd2 == "1") + { + result = accountMgr->replyToInvitation(cmd, true, &onDelete); + } + else + { + result = accountMgr->replyToInvitation(cmd, false, &onDelete); + } + break; - case 20: - goto exit; + case 17: + result = accountMgr->cancelObserveGroup(); + break; - default: - break; + case 18: + result = accountMgr->cancelObserveInvitation(); + break; + case 30: + int opt; + cout + << "\n---------------------------------------------------------------------\n"; + cout << " w/ query? (1:yes / 2:no)" << endl; + cout + << "---------------------------------------------------------------------\n\n"; + opt = insertNumber(); + uri = OC_RSRVD_WELL_KNOWN_URI; + if (opt == 1) + { + string query; + cout << "\ninsert query : "; + cin >> query; + uri += "?"; + uri += query; + } + result = OC::OCPlatform::findResource(accountMgr->host(), uri, + accountMgr->connectivityType(), &onFoundResource); + break; + case 31: + { + uri = binarySwitch.getResourceUri(); + rt = binarySwitch.getResourceType()[0]; + itf = binarySwitch.getInterfaces()[0]; + cout << " RESOURCE URI: " << uri << endl; + cout << " RESOURCE RT: " << rt << endl; + cout << " RESOURCE ITF: " << itf << endl; + + result = OCPlatform::registerResource(binarySwitch.m_handle, uri, rt, itf, + bind(&BinarySwitchResource::entityHandler, &binarySwitch, + placeholders::_1), OC_OBSERVABLE); + + if (result != OC_STACK_OK) + { + cout << "Resource registration was unsuccessful" << endl; + } + + cout << "Publishing resources to cloud \n\n"; + ResourceHandles resourceHandles; + OCDeviceInfo devInfoBinarySwitch; + OCStringLL deviceType; + + deviceType.value = "oic.d.binaryswitch"; + deviceType.next = NULL; + devInfoBinarySwitch.deviceName = "FAC_2016"; + devInfoBinarySwitch.types = &deviceType; + devInfoBinarySwitch.specVersion = NULL; + devInfoBinarySwitch.dataModelVersions = NULL; + + OCPlatform::registerDeviceInfo(devInfoBinarySwitch); + + resourceHandles.push_back(binarySwitch.m_handle); + + result = RDClient::Instance().publishResourceToRD(g_host, + OCConnectivityType::CT_ADAPTER_TCP, resourceHandles, &onPublish); + + cout << " result: " << result + << " Waiting Publish user resource response from cloud" << endl; + g_callbackLock.wait(lock); + break; + } + case 41: + { + cout << "my user uuid : " << g_uid << endl; + cout << "my accesstoken : " << g_accesstoken << endl; + cout << "my refreshtoken : " << g_refreshtoken << endl; + cout << "my tokentype : " << g_tokentype << endl; + cout << "my serverId : " << g_serverId << endl; + + result = OC_STACK_OK; + break; + } + case 50: + goto exit; + default: + break; } - if (result != OC_STACK_OK) { cout << "Error, return code: " << result << endl; @@ -452,3 +1041,4 @@ int main(int argc, char *argv[]) exit: return 0; } + diff --git a/cloud/samples/client/messagequeue/mq_publisher.cpp b/cloud/samples/client/messagequeue/mq_publisher.cpp index ad8afdc..a0f0b78 100644 --- a/cloud/samples/client/messagequeue/mq_publisher.cpp +++ b/cloud/samples/client/messagequeue/mq_publisher.cpp @@ -37,11 +37,18 @@ #include #include +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) +#include "ocprovisioningmanager.h" +#include "mbedtls/ssl_ciphersuites.h" +#include +#endif // WITH_DTLS__ or __WITH_TLS__ + using namespace OC; using namespace std; #define DEFAULT_MQ_BROKER_URI "/oic/ps" +string g_host; OC::OCResource::Ptr g_mqBrokerResource = nullptr; OC::OCResource::Ptr g_mqSelectedTopicResource = nullptr; @@ -143,6 +150,51 @@ void handleLoginoutCB(const HeaderOptions &, g_callbackLock.notify_all(); } +int saveTrustCert(void) +{ + OCStackResult res = OC_STACK_ERROR; + uint16_t g_credId = 0; + + cout << "Save Trust Cert. Chain into Cred of SVR" < 0) + { + trustCertChainArray.data = (uint8_t *)malloc(fsize); + trustCertChainArray.len = fsize; + if (NULL == trustCertChainArray.data) + { + cout << "Failed to allocate memory" << endl; + fclose(fp); + return res; + } + rewind(fp); + if (fsize != fread(trustCertChainArray.data, 1, fsize, fp)) + { + cout << "Certiface not read completely" << endl; + } + fclose(fp); + } + } + + res = OCSaveTrustCertChain(trustCertChainArray.data, trustCertChainArray.len, OIC_ENCODING_PEM,&g_credId); + + if(OC_STACK_OK != res) + { + cout << "OCSaveTrustCertChainBin API error" << endl; + return res; + } + cout << "CredId of Saved Trust Cert. Chain into Cred of SVR : " << g_credId << endl; + + return res; +} + static FILE *client_open(const char *path, const char *mode) { if (0 == strcmp(path, OC_SECURITY_DB_DAT_FILE_NAME)) @@ -157,14 +209,14 @@ static FILE *client_open(const char *path, const char *mode) int main(int argc, char *argv[]) { - if (argc != 4 && argc != 5) - { - cout << "Put \"[host-ipaddress:port] [authprovider] [authcode]\" for sign-up and sign-in" - << endl; - cout << "Put \"[host-ipaddress:port] [uid] [accessToken] 1\" for sign-in" << - endl; - return 0; - } + if (argc != 5) + { + cout << "Put \"[host-ipaddress:port] [authprovider] [authcode] [tls mode(0,1)]\" for sign-up and sign-in and publish resources" + << endl; + cout << "Put \"[host-ipaddress:port] [uid] [accessToken] [tls mode(0,1)]\" for sign-in and publish resources" << + endl; + return 0; + } OCPersistentStorage ps{ client_open, fread, fwrite, fclose, unlink }; @@ -182,17 +234,42 @@ int main(int argc, char *argv[]) OCStackResult result = OC_STACK_ERROR; - string host = "coap+tcp://"; - host += argv[1]; + g_host = "coap+tcp://"; - OCAccountManager::Ptr accountMgr = OCPlatform::constructAccountManagerObject(host, - CT_ADAPTER_TCP); + if (!strcmp(argv[4], "1")) + { +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) + g_host = "coaps+tcp://"; +#endif + } - mutex blocker; - unique_lock lock(blocker); + g_host += argv[1]; - if (argc == 5) - { + OCAccountManager::Ptr accountMgr = OCPlatform::constructAccountManagerObject(g_host, + CT_ADAPTER_TCP); + + if (!strcmp(argv[4], "1")) + { +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) + cout << "Security Mode" << endl; + if (CA_STATUS_OK != saveTrustCert()) + { + cout << "saveTrustCert returned an error" << endl; + } + + uint16_t cipher = MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256; + if (CA_STATUS_OK != CASelectCipherSuite(cipher, CA_ADAPTER_TCP)) + { + cout << "CASelectCipherSuite returned an error" << endl; + } +#endif + } + + mutex blocker; + unique_lock lock(blocker); + + if (strlen(argv[2]) > 35) + { accountMgr->signIn(argv[2], argv[3], &handleLoginoutCB); g_callbackLock.wait(lock); } @@ -205,7 +282,7 @@ int main(int argc, char *argv[]) } // MQ broker resource - g_mqBrokerResource = OCPlatform::constructResourceObject(host, DEFAULT_MQ_BROKER_URI, + g_mqBrokerResource = OCPlatform::constructResourceObject(g_host, DEFAULT_MQ_BROKER_URI, static_cast(CT_ADAPTER_TCP | CT_IP_USE_V4), false, { string("oic.wk.ps") }, { string(DEFAULT_INTERFACE) }); @@ -311,4 +388,4 @@ int main(int argc, char *argv[]) exit: return 0; -} \ No newline at end of file +} diff --git a/cloud/samples/client/messagequeue/mq_subscriber.cpp b/cloud/samples/client/messagequeue/mq_subscriber.cpp index 9b876d5..63a74eb 100644 --- a/cloud/samples/client/messagequeue/mq_subscriber.cpp +++ b/cloud/samples/client/messagequeue/mq_subscriber.cpp @@ -37,11 +37,18 @@ #include #include +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) +#include "ocprovisioningmanager.h" +#include "mbedtls/ssl_ciphersuites.h" +#include +#endif // WITH_DTLS__ or __WITH_TLS__ + using namespace OC; using namespace std; #define DEFAULT_MQ_BROKER_URI "/oic/ps" +string g_host; OC::OCResource::Ptr g_mqBrokerResource = nullptr; OC::OCResource::Ptr g_mqSelectedTopicResource = nullptr; @@ -157,6 +164,51 @@ void handleLoginoutCB(const HeaderOptions &, g_callbackLock.notify_all(); } +int saveTrustCert(void) +{ + OCStackResult res = OC_STACK_ERROR; + uint16_t g_credId = 0; + + cout << "Save Trust Cert. Chain into Cred of SVR" < 0) + { + trustCertChainArray.data = (uint8_t *)malloc(fsize); + trustCertChainArray.len = fsize; + if (NULL == trustCertChainArray.data) + { + cout << "Failed to allocate memory" << endl; + fclose(fp); + return res; + } + rewind(fp); + if (fsize != fread(trustCertChainArray.data, 1, fsize, fp)) + { + cout << "Certiface not read completely" << endl; + } + fclose(fp); + } + } + + res = OCSaveTrustCertChain(trustCertChainArray.data, trustCertChainArray.len, OIC_ENCODING_PEM,&g_credId); + + if(OC_STACK_OK != res) + { + cout << "OCSaveTrustCertChainBin API error" << endl; + return res; + } + cout << "CredId of Saved Trust Cert. Chain into Cred of SVR : " << g_credId << endl; + + return res; +} + static FILE *client_open(const char *path, const char *mode) { if (0 == strcmp(path, OC_SECURITY_DB_DAT_FILE_NAME)) @@ -171,14 +223,14 @@ static FILE *client_open(const char *path, const char *mode) int main(int argc, char *argv[]) { - if (argc != 4 && argc != 5) - { - cout << "Put \"[host-ipaddress:port] [authprovider] [authcode]\" for sign-up and sign-in" - << endl; - cout << "Put \"[host-ipaddress:port] [uid] [accessToken] 1\" for sign-in" << - endl; - return 0; - } + if (argc != 5) + { + cout << "Put \"[host-ipaddress:port] [authprovider] [authcode] [tls mode(0,1)]\" for sign-up and sign-in and publish resources" + << endl; + cout << "Put \"[host-ipaddress:port] [uid] [accessToken] [tls mode(0,1)]\" for sign-in and publish resources" << + endl; + return 0; + } OCPersistentStorage ps{ client_open, fread, fwrite, fclose, unlink }; @@ -196,17 +248,42 @@ int main(int argc, char *argv[]) OCStackResult result = OC_STACK_ERROR; - string host = "coap+tcp://"; - host += argv[1]; - - OCAccountManager::Ptr accountMgr = OCPlatform::constructAccountManagerObject(host, - CT_ADAPTER_TCP); - - mutex blocker; - unique_lock lock(blocker); - - if (argc == 5) - { + g_host = "coap+tcp://"; + + if (!strcmp(argv[4], "1")) + { +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) + g_host = "coaps+tcp://"; +#endif + } + + g_host += argv[1]; + + OCAccountManager::Ptr accountMgr = OCPlatform::constructAccountManagerObject(g_host, + CT_ADAPTER_TCP); + + if (!strcmp(argv[4], "1")) + { +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) + cout << "Security Mode" << endl; + if (CA_STATUS_OK != saveTrustCert()) + { + cout << "saveTrustCert returned an error" << endl; + } + + uint16_t cipher = MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256; + if (CA_STATUS_OK != CASelectCipherSuite(cipher, CA_ADAPTER_TCP)) + { + cout << "CASelectCipherSuite returned an error" << endl; + } +#endif + } + + mutex blocker; + unique_lock lock(blocker); + + if (strlen(argv[2]) > 35) + { accountMgr->signIn(argv[2], argv[3], &handleLoginoutCB); g_callbackLock.wait(lock); } @@ -219,7 +296,7 @@ int main(int argc, char *argv[]) } // MQ broker resource - g_mqBrokerResource = OCPlatform::constructResourceObject(host, DEFAULT_MQ_BROKER_URI, + g_mqBrokerResource = OCPlatform::constructResourceObject(g_host, DEFAULT_MQ_BROKER_URI, static_cast(CT_ADAPTER_TCP | CT_IP_USE_V4), false, { string("oic.wk.ps") }, { string(DEFAULT_INTERFACE) }); diff --git a/cloud/samples/client/rootca.crt b/cloud/samples/client/rootca.crt new file mode 100644 index 0000000..ee80fa4 --- /dev/null +++ b/cloud/samples/client/rootca.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDjDCCAnQCAQEwDQYJKoZIhvcNAQELBQAwgYsxCzAJBgNVBAYTAktSMQ4wDAYD +VQQIDAVTZW91bDEPMA0GA1UEBwwGVW15ZW9uMREwDwYDVQQKDAhTYW1zdW5nIDEU +MBIGA1UECwwLT0NGIFJvb3QgQ0ExMjAwBgNVBAMMKXV1aWQ6MzEzMTMxMzEtMzEz +MS0zMTMxLTMxMzEtMzEzMTMxMzEzMTMxMB4XDTE2MTAyODA0MjEyMloXDTI2MTAy +NjA0MjEyMlowgYsxCzAJBgNVBAYTAktSMQ4wDAYDVQQIDAVTZW91bDEPMA0GA1UE +BwwGVW15ZW9uMREwDwYDVQQKDAhTYW1zdW5nIDEUMBIGA1UECwwLT0NGIFJvb3Qg +Q0ExMjAwBgNVBAMMKXV1aWQ6MzEzMTMxMzEtMzEzMS0zMTMxLTMxMzEtMzEzMTMx +MzEzMTMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3EJwn+NfeW9Y +RLDoOUSg45AvkqsMeNBv8ZTqWyY5nAeyESQsDejacm6dSpzMP/p5y1KBWYszKOXr +CUtrkch8VxOtt4egiv3Tschl16W1W7ril8EEbX8zoEcuExfoLdPZhDtRl8ROdG3t +NE0r/Fv5ubTEwW0K3JgIwykB4OAsO2aQtCuZ32cZlg5UcW3LAXpxJ7cEkMR2xhcN +xbg0dgbyy5BiWit3grXXJBkopq/ADCRUIVzpLjxeFTVshWw9+AA1IUZaG64fkbLG +pzdYFVsuRvMlyEwWrMm23/hT8x0eywvPX5k/N1s6I0KiE8FitVi5bgUph3iCNLE/ +1a/oLrtWyQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQDHq9X9YofW3IN8R61r0raN +tacYMumZFZfPOEcHHGvTkPrMygUNfTM+g6XEzOvlBB4dd6UE5EsVnRkQP0wvaaJx +3Js/zQMkAXeVRzDg/YowynuG+t4VvoQl/1uNDUKjU9z+yv+vQjNctzeKhvAJxWGO +ZtpgIslUhMtGBjWQDNd2APf8yOcD50yVwUpcp4WGbqaaKxn+rixu8jk1NEas0EHD +XBytAgEdOeBQplv6W+W1fG3j0PMolkWaPIvjSvMk0m11h4GR5Kyx3gRQS74gurG/ +DboAZ+DJMe7hMh4coOwnOuS8euPtxEPD3IkYVAT4aFPIvTkiri0EYimgtQd+M45f +-----END CERTIFICATE----- diff --git a/cloud/samples/client/thin_light/thin_room_light.cpp b/cloud/samples/client/thin_light/thin_room_light.cpp index a54e72b..a7ada69 100644 --- a/cloud/samples/client/thin_light/thin_room_light.cpp +++ b/cloud/samples/client/thin_light/thin_room_light.cpp @@ -36,6 +36,12 @@ #include "rd_client.h" #include "OCPlatform.h" +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) +#include "ocprovisioningmanager.h" +#include "mbedtls/ssl_ciphersuites.h" +#include +#endif // WITH_DTLS__ or __WITH_TLS__ + using namespace std; #define VERIFY_SUCCESS(op) \ @@ -562,7 +568,9 @@ void printRepresentation(OCRepPayloadValue *value) } } -string g_host = "coap+tcp://"; + + +string g_host; OCStackApplicationResult handleLoginoutCB(void *ctx, OCDoHandle /*handle*/, OCClientResponse *clientResponse) @@ -636,6 +644,51 @@ void PrintUsage() } +int saveTrustCert(void) +{ + OCStackResult res = OC_STACK_ERROR; + uint16_t g_credId = 0; + + cout << "Save Trust Cert. Chain into Cred of SVR" < 0) + { + trustCertChainArray.data = (uint8_t *)malloc(fsize); + trustCertChainArray.len = fsize; + if (NULL == trustCertChainArray.data) + { + cout << "Failed to allocate memory" << endl; + fclose(fp); + return res; + } + rewind(fp); + if (fsize != fread(trustCertChainArray.data, 1, fsize, fp)) + { + cout << "Certiface not read completely" << endl; + } + fclose(fp); + } + } + + res = OCSaveTrustCertChain(trustCertChainArray.data, trustCertChainArray.len, OIC_ENCODING_PEM,&g_credId); + + if(OC_STACK_OK != res) + { + cout << "OCSaveTrustCertChainBin API error" << endl; + return res; + } + cout << "CredId of Saved Trust Cert. Chain into Cred of SVR : " << g_credId << endl; + + return res; +} + static FILE *client_open(const char *path, const char *mode) { if (0 == strcmp(path, OC_SECURITY_DB_DAT_FILE_NAME)) @@ -650,29 +703,41 @@ static FILE *client_open(const char *path, const char *mode) int main(int argc, char *argv[]) { + if (argc < 3) + { + cout << "Put \"[host-ipaddress:port] [tls mode(0,1)] \" for sign-up" + << endl; + cout << "Put \"[host-ipaddress:port] [uid] [accessToken] [tls mode(0,1)]\" for sign-in and publish resources" << + endl; + cout << "Put \"[host-ipaddress:port] [uid] [refreshToken] refresh [tls mode(0,1)]\" for accessToken to refresh" << + endl; + return 0; + } + string uId; string accessToken; string refreshToken; string authProvider; string authCode; - - OCMode stackMode = OC_CLIENT_SERVER; - + string tlsMode; + + OCMode stackMode = OC_CLIENT_SERVER; + tlsMode = argv[argc - 1]; switch (argc) { - case 2: + case 3: cout << "Put auth provider name(ex: github)" << endl; cin >> authProvider; cout << "Put auth code(provided by auth provider)" << endl; cin >> authCode; break; - case 4: + case 5: uId = argv[2]; accessToken = argv[3]; break; - case 5: + case 6: uId = argv[2]; refreshToken = argv[3]; break; @@ -682,7 +747,16 @@ int main(int argc, char *argv[]) return 0; } - g_host += argv[1]; + g_host = "coap+tcp://"; + + if (tlsMode == "1") + { +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) + g_host = "coaps+tcp://"; +#endif + } + + g_host += argv[1]; cout << "Host " << g_host.c_str() << endl; @@ -702,23 +776,40 @@ int main(int argc, char *argv[]) OCStackResult res = OC_STACK_ERROR; + if (tlsMode == "1") + { +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) + cout << "Security Mode" << endl; + if (CA_STATUS_OK != saveTrustCert()) + { + cout << "saveTrustCert returned an error" << endl; + } + + uint16_t cipher = MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256; + if (CA_STATUS_OK != CASelectCipherSuite(cipher, CA_ADAPTER_TCP)) + { + cout << "CASelectCipherSuite returned an error" << endl; + } +#endif + } + switch (argc) { - case 2: + case 3: cout << "Sign-Up to cloud using " << authProvider << " " << authCode << endl; res = OCCloudSignup(g_host.c_str(), OCGetServerInstanceIDString(), authProvider.c_str(), authCode.c_str(), handleRegisterCB); cout << "OCCloudSignup return " << res << endl; break; - case 4: + case 5: cout << "Sign-In to cloud using " << accessToken << endl; res = OCCloudLogin(g_host.c_str(), uId.c_str(), OCGetServerInstanceIDString(), accessToken.c_str(), handleLoginoutCB); cout << "OCCloudLogin return " << res << endl; break; - case 5: + case 6: cout << "Token refresh to cloud using the refresh token " << refreshToken << endl; res = OCCloudRefresh(g_host.c_str(), DEFAULT_AUTH_REFRESH, uId.c_str(), OCGetServerInstanceIDString(), refreshToken.c_str(), handleRegisterCB); -- 2.7.4