From abe770f68766642d6b07844596fa6547a0f0c2d5 Mon Sep 17 00:00:00 2001 From: Ashwini Kumar Date: Fri, 4 Nov 2016 17:56:38 +0530 Subject: [PATCH] Added C and C++ callback API for TrustCertChain Change Notification. patch #2,3,4 : Fix callback context at RI layer patch #5: Address review comments Change-Id: I1d776a01cfb41074ce518ee20ddda1ce7ccde40f Signed-off-by: Sandeep Sharma Signed-off-by: Ashwini Kumar Reviewed-on: https://gerrit.iotivity.org/gerrit/14033 Tested-by: jenkins-iotivity Reviewed-by: Randeep Singh --- .../include/internal/secureresourceprovider.h | 16 +++++ .../include/ocprovisioningmanager.h | 12 ++++ .../provisioning/src/ocprovisioningmanager.c | 20 +++++++ .../provisioning/src/secureresourceprovider.c | 33 +++++++++++ resource/csdk/stack/include/octypes.h | 22 +++++++ resource/include/OCProvisioningManager.h | 36 ++++++++++- .../examples/provisioningclient.cpp | 10 ++++ .../src/OCProvisioningManager.cpp | 59 ++++++++++++++++++- 8 files changed, 206 insertions(+), 2 deletions(-) diff --git a/resource/csdk/security/provisioning/include/internal/secureresourceprovider.h b/resource/csdk/security/provisioning/include/internal/secureresourceprovider.h index 876dfd93d..f828606ae 100644 --- a/resource/csdk/security/provisioning/include/internal/secureresourceprovider.h +++ b/resource/csdk/security/provisioning/include/internal/secureresourceprovider.h @@ -24,6 +24,8 @@ #include "ocstack.h" #include "securevirtualresourcetypes.h" #include "pmtypes.h" +#include "octypes.h" + #ifdef __cplusplus extern "C" @@ -111,6 +113,20 @@ OCStackResult SRPSaveTrustCertChain(uint8_t *trustCertChain, size_t chainSize, */ OCStackResult SRPSaveOwnCertChain(OicSecCert_t * cert, OicSecKey_t * key, uint16_t *credId); +/** + * function to register callback, for getting notification for TrustCertChain change. + * + * @param[in] ctx user context to be passed. + * @param[in] TrustCertChainChangeCB notifier callback function + * @return OC_STACK_OK in case of success and other value otherwise. + */ +OCStackResult SRPRegisterTrustCertChainNotifier(void *ctx, TrustCertChainChangeCB callback); + +/** + * function to de-register TrustCertChain notification callback. + */ +void SRPRemoveTrustCertChainNotifier(void); + #endif // __WITH_DTLS__ || __WITH_TLS__ /** * API to send Direct-Pairing Configuration to a device. diff --git a/resource/csdk/security/provisioning/include/ocprovisioningmanager.h b/resource/csdk/security/provisioning/include/ocprovisioningmanager.h index 5153963f4..0c4300344 100644 --- a/resource/csdk/security/provisioning/include/ocprovisioningmanager.h +++ b/resource/csdk/security/provisioning/include/ocprovisioningmanager.h @@ -451,6 +451,18 @@ OCStackResult OCProvisionTrustCertChain(void *ctx, OicSecCredType_t type, uint16 */ OCStackResult OCSaveTrustCertChain(uint8_t *trustCertChain, size_t chainSize, OicEncodingType_t encodingType, uint16_t *credId); +/** + * function to register callback, for getting notification for TrustCertChain change. + * + * @param[in] TrustCertChainChangeCB notifier callback function + * @return OC_STACK_OK in case of success and other value otherwise. + */ +OCStackResult OCRegisterTrustCertChainNotifier(void *cb, TrustCertChainChangeCB CB); + +/** + * function to de-register TrustCertChain notification callback. + */ +void OCRemoveTrustCertChainNotifier(void); /* * Function to read Trust certificate chain from SVR. diff --git a/resource/csdk/security/provisioning/src/ocprovisioningmanager.c b/resource/csdk/security/provisioning/src/ocprovisioningmanager.c index 1ac5d428a..549edfd89 100644 --- a/resource/csdk/security/provisioning/src/ocprovisioningmanager.c +++ b/resource/csdk/security/provisioning/src/ocprovisioningmanager.c @@ -1294,5 +1294,25 @@ OCStackResult OCSaveTrustCertChain(uint8_t *trustCertChain, size_t chainSize, return SRPSaveTrustCertChain(trustCertChain, chainSize, encodingType, credId); } +/** + * function to register notifier for Trustcertchain change. + * + * @param[in] ctx user context. + * @param[in] TrustCertChainChangeCB notification callback fucntion. + * @return @return OC_STACK_OK in case of success and other value otherwise. + */ +OCStackResult OCRegisterTrustCertChainNotifier(void *ctx, TrustCertChainChangeCB Callback) +{ + SRPRegisterTrustCertChainNotifier(ctx, Callback); + return; +} + +/** + * function to de-register notifier for Trustcertchain change. + */ +void OCRemoveTrustCertChainNotifier() +{ + return SRPRemoveTrustCertChainNotifier(); +} #endif // __WITH_DTLS__ || __WITH_TLS__ diff --git a/resource/csdk/security/provisioning/src/secureresourceprovider.c b/resource/csdk/security/provisioning/src/secureresourceprovider.c index 92084200a..be479eaf4 100644 --- a/resource/csdk/security/provisioning/src/secureresourceprovider.c +++ b/resource/csdk/security/provisioning/src/secureresourceprovider.c @@ -65,6 +65,9 @@ #define VERIFY_SUCCESS(tag, op, logLevel, retValue) { if (!(op)) \ {OIC_LOG((logLevel), tag, #op " failed!!"); return retValue;} } + +trustCertChainContext_t g_trustCertChainNotifier; + /** * Structure to carry credential data to callback. */ @@ -452,6 +455,26 @@ static OCStackResult provisionCertCred(const OicSecCred_t *cred, return ret; } +OCStackResult SRPRegisterTrustCertChainNotifier(void *ctx, TrustCertChainChangeCB callback) +{ + if (g_trustCertChainNotifier.callback) + { + OIC_LOG(ERROR, TAG, "Can't register Notifier, Unregister previous one"); + return OC_STACK_ERROR; + } + + g_trustCertChainNotifier.callback = callback; + g_trustCertChainNotifier.context = ctx; + return OC_STACK_OK; +} + +void SRPRemoveTrustCertChainNotifier() +{ + g_trustCertChainNotifier.callback = NULL; + g_trustCertChainNotifier.context = NULL; + return; +} + /** * Callback handler for handling callback of certificate provisioning device. * @@ -629,6 +652,16 @@ OCStackResult SRPSaveTrustCertChain(uint8_t *trustCertChain, size_t chainSize, } *credId = cred->credId; + if (g_trustCertChainNotifier.callback) + { + uint8_t *certChain = (uint8_t*)OICCalloc(1, sizeof(uint8_t) * chainSize); + VERIFY_NON_NULL(TAG, certChain, ERROR, OC_STACK_NO_MEMORY); + memcpy(certChain, trustCertChain, chainSize); + g_trustCertChainNotifier.callback(g_trustCertChainNotifier.context, credId, + certChain, chainSize); + OICFree(certChain); + } + OIC_LOG(DEBUG, TAG, "OUT SRPSaveTrustCertChain"); return res; diff --git a/resource/csdk/stack/include/octypes.h b/resource/csdk/stack/include/octypes.h index 073902cee..3429ecc0b 100644 --- a/resource/csdk/stack/include/octypes.h +++ b/resource/csdk/stack/include/octypes.h @@ -1694,6 +1694,28 @@ typedef OCEntityHandlerResult (*OCDeviceEntityHandler) typedef void (*OCDirectPairingCB)(void *ctx, OCDPDev_t *peer, OCStackResult result); //#endif // DIRECT_PAIRING +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) +/** + * Callback function definition for Change in TrustCertChain + * + * @param[IN] ctx - user context returned in the callback. + * @param[IN] credId - trustCertChain changed for this ID + * @param[IN] trustCertChain - trustcertchain binary blob. + * @param[IN] chainSize - size of trustchain + */ +typedef void (*TrustCertChainChangeCB)(void *ctx, uint16_t credId, uint8_t *trustCertChain, + size_t chainSize); + +/** + * certChain context structure. + */ +typedef struct trustCertChainContext +{ + TrustCertChainChangeCB callback; + void *context; +} trustCertChainContext_t; +#endif + #ifdef __cplusplus } #endif // __cplusplus diff --git a/resource/include/OCProvisioningManager.h b/resource/include/OCProvisioningManager.h index 93f6b2c3d..dd60cedf2 100644 --- a/resource/include/OCProvisioningManager.h +++ b/resource/include/OCProvisioningManager.h @@ -36,6 +36,8 @@ namespace OC typedef std::vector UuidList_t; typedef std::vector PMResultList_t; typedef std::function ResultCallBack; + typedef std::functionCertChainCallBack; struct ProvisionContext { @@ -43,6 +45,11 @@ namespace OC ProvisionContext(ResultCallBack cb) : callback(cb){} }; + struct TrustCertChainContext + { + CertChainCallBack callback; + TrustCertChainContext(CertChainCallBack cb) : callback(cb){} + }; /** * This class is for credential's to be set to devices. * The types supported are @@ -229,7 +236,6 @@ namespace OC static OCStackResult saveTrustCertChain(uint8_t *trustCertChain, size_t chainSize, OicEncodingType_t encodingType, uint16_t *credId); - /* * API to read Trust certificate chain from SVR. * Caller must free when done using the returned trust certificate @@ -240,6 +246,34 @@ namespace OC */ static OCStackResult readTrustCertChain(uint16_t credId, uint8_t **trustCertChain, size_t *chainSize); + + /** + * API to register Notifier for trustCertChain change. + * + * @param[in] TrustCertChainChangeCB trustCertChain Change will be + * notified asynchronously. User need to "delete[]" trustCertChain + * in the callback function. + * @return OC_STACK_OK in case of success and other value otherwise. + */ + static OCStackResult registerTrustCertChangeNotifier(CertChainCallBack); + + /** + * API to remove Already registered Notifier. + * + *@return OC_STACK_OK always, kept it for symmetry. + */ + static OCStackResult removeTrustCertChangeNotifier(); + + /** + * Notifier wrapper for trustCertChain change. + * + * @param[in] ctx User context returned in callback + * @param[in] credId trustCertChain changed for this ID + * @param[in] trustCertChain trustcertchain binary blob + * @param[in] chainSize size of trustCertChain + */ + static void certCallbackWrapper(void* ctx, uint16_t credId, uint8_t *trustCertChain, + size_t chainSize); #endif // __WITH_DTLS__ || __WITH_TLS__ }; diff --git a/resource/provisioning/examples/provisioningclient.cpp b/resource/provisioning/examples/provisioningclient.cpp index 9f78e8930..53e9c1072 100644 --- a/resource/provisioning/examples/provisioningclient.cpp +++ b/resource/provisioning/examples/provisioningclient.cpp @@ -846,6 +846,12 @@ static int saveTrustCert(void) return 0; } + +void certChainCallBack(uint16_t credId, uint8_t *trustCertChain,size_t chainSize) +{ + OIC_LOG_V(INFO, TAG, "trustCertChain Changed for credId %u", credId); + return; +} #endif // __WITH_DTLS__ or __WITH_TLS__ int main(void) @@ -1287,10 +1293,14 @@ int main(void) #if defined(__WITH_DTLS__) || defined(__WITH_TLS__) case 13: { + std::cout<< "registering cert chain change notifier"<(ctx); + uint8_t *certChain = new uint8_t[chainSize]; + memcpy(certChain, trustCertChain, chainSize); + std::thread exec(context->callback, credId, certChain, chainSize); + exec.detach(); + delete context; + } + + OCStackResult OCSecure::registerTrustCertChangeNotifier(CertChainCallBack callback) + { + if (!callback) + { + oclog() <<"callback can not be null"; + return OC_STACK_INVALID_CALLBACK; + } + + OCStackResult result; + auto cLock = OCPlatform_impl::Instance().csdkLock().lock(); + + if (cLock) + { + TrustCertChainContext* context = new TrustCertChainContext(callback); + std::lock_guard lock(*cLock); + result = OCRegisterTrustCertChainNotifier(static_cast(context), + &OCSecure::certCallbackWrapper); + } + else + { + oclog() <<"Mutex not found"; + result = OC_STACK_ERROR; + } + return result; + } + + + OCStackResult OCSecure::removeTrustCertChangeNotifier() + { + OCStackResult result; + auto cLock = OCPlatform_impl::Instance().csdkLock().lock(); + + if (cLock) + { + std::lock_guard lock(*cLock); + OCRemoveTrustCertChainNotifier(); + result = OC_STACK_OK; + } + else + { + oclog() <<"Mutex not found"; + result = OC_STACK_ERROR; + } + return result; + } #endif // __WITH_DTLS__ || __WITH_TLS__ void OCSecureResource::callbackWrapper(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError) -- 2.34.1