From: Dan Mihai Date: Tue, 14 Feb 2017 23:04:11 +0000 (-0800) Subject: [IOT-1801] Implement OCF Security CR1339 X-Git-Tag: 1.3.0~607 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bfbff11f44b56cb1130907587d600e82d57a8a28;p=platform%2Fupstream%2Fiotivity.git [IOT-1801] Implement OCF Security CR1339 1. Use the initial Ownership Transfer session even after setting-up the Owner Credential, when onboarding Servers based on OCF 1.0 - rather than closing that session and establishing a new one. 2. Posting the Owner Credential ACL might fail for older Servers. In that case, close the initial Ownership Transfer session and establish a new session, for compatibility with those older Servers. Change-Id: If242c0af4ec05ad9ca144c274ee5385bc7738d92 Signed-off-by: Dan Mihai Reviewed-on: https://gerrit.iotivity.org/gerrit/17279 Reviewed-by: Kevin Kane Tested-by: jenkins-iotivity --- diff --git a/resource/csdk/connectivity/api/cacommon.h b/resource/csdk/connectivity/api/cacommon.h index a952477..089f67b 100755 --- a/resource/csdk/connectivity/api/cacommon.h +++ b/resource/csdk/connectivity/api/cacommon.h @@ -324,9 +324,17 @@ typedef struct // TODO change name to deviceId CARemoteId_t identity; /**< endpoint device uuid */ CARemoteId_t userId; /**< endpoint user uuid */ + uint32_t attributes; } CASecureEndpoint_t; /** + * Endpoint used for security administration - a special type of identity that + * bypasses Access Control Entry checks for SVR resources, while the device is + * not owned yet. + */ +#define CA_SECURE_ENDPOINT_ATTRIBUTE_ADMINISTRATOR 0x1 + +/** * Enums for CA return values. */ typedef enum diff --git a/resource/csdk/connectivity/api/casecurityinterface.h b/resource/csdk/connectivity/api/casecurityinterface.h index 8a39fc8..1318d2d 100644 --- a/resource/csdk/connectivity/api/casecurityinterface.h +++ b/resource/csdk/connectivity/api/casecurityinterface.h @@ -77,7 +77,27 @@ typedef int (*CAgetPskCredentialsHandler)(CADtlsPskCredType_t type, */ const CASecureEndpoint_t *CAGetSecureEndpointData(const CAEndpoint_t *peer); #endif //MULTIPLE_OWNER -#endif + +/** + * Adds a bit to the attributes field of a secure endpoint. + * + * @param[in] peer remote address + * @param[in] newAttribute bit to be added to the attributes field + * + * @return true if the secure endpoint has been found, false otherwise. + */ +bool CASetSecureEndpointAttribute(const CAEndpoint_t* peer, uint32_t newAttribute); + +/** + * Gets the attributes field of a secure endpoint. + * + * @param[in] peer remote address + * @param[out] allAttributes all the attributes bits for that remote address + * + * @return true if the secure endpoint has been found, false otherwise. + */ +bool CAGetSecureEndpointAttributes(const CAEndpoint_t* peer, uint32_t* allAttributes); +#endif // #if defined(__WITH_DTLS__) || defined(__WITH_TLS__) /** * This internal callback is used by CA layer to diff --git a/resource/csdk/connectivity/inc/ca_adapter_net_ssl.h b/resource/csdk/connectivity/inc/ca_adapter_net_ssl.h index cad229d..e6098d8 100644 --- a/resource/csdk/connectivity/inc/ca_adapter_net_ssl.h +++ b/resource/csdk/connectivity/inc/ca_adapter_net_ssl.h @@ -190,6 +190,26 @@ CAResult_t CAsslGenerateOwnerPsk(const CAEndpoint_t *endpoint, const CASecureEndpoint_t *GetCASecureEndpointData(const CAEndpoint_t* peer); #endif +/** + * Adds a bit to the attributes field of a secure endpoint. + * + * @param[in] peer remote address + * @param[in] newAttribute bit to be added to the attributes field + * + * @return true if the secure endpoint has been found, false otherwise. + */ +bool SetCASecureEndpointAttribute(const CAEndpoint_t* peer, uint32_t newAttribute); + +/** + * Gets the attributes field of a secure endpoint. + * + * @param[in] peer remote address + * @param[out] allAttributes all the attributes bits for that remote address + * + * @return true if the secure endpoint has been found, false otherwise. + */ +bool GetCASecureEndpointAttributes(const CAEndpoint_t* peer, uint32_t* allAttributes); + #ifdef __cplusplus } #endif //__cplusplus diff --git a/resource/csdk/connectivity/src/adapter_util/ca_adapter_net_ssl.c b/resource/csdk/connectivity/src/adapter_util/ca_adapter_net_ssl.c index d8a7a89..fcb4a0c 100644 --- a/resource/csdk/connectivity/src/adapter_util/ca_adapter_net_ssl.c +++ b/resource/csdk/connectivity/src/adapter_util/ca_adapter_net_ssl.c @@ -939,6 +939,91 @@ const CASecureEndpoint_t *GetCASecureEndpointData(const CAEndpoint_t* peer) #endif /** + * Adds a bit to the attributes field of a secure endpoint. + * + * @param[in] peer remote address + * @param[in] newAttribute bit to be added to the attributes field + * + * @return true if the secure endpoint has been found, false otherwise. + */ +bool SetCASecureEndpointAttribute(const CAEndpoint_t* peer, uint32_t newAttribute) +{ + bool result = false; + + OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s(peer = %s:%u, attribute = %#x)", __func__, + peer->addr, (uint32_t)peer->port, newAttribute); + + oc_mutex_lock(g_sslContextMutex); + + if (NULL == g_caSslContext) + { + OIC_LOG(ERROR, NET_SSL_TAG, "Context is NULL"); + } + else + { + SslEndPoint_t* sslPeer = GetSslPeer(peer); + + if (!sslPeer) + { + OIC_LOG(ERROR, NET_SSL_TAG, "SSL peer not found"); + } + else + { + sslPeer->sep.attributes |= newAttribute; + result = true; + } + } + + oc_mutex_unlock(g_sslContextMutex); + + OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s -> %s", __func__, result ? "success" : "failed"); + return result; +} + +/** + * Gets the attributes field of a secure endpoint. + * + * @param[in] peer remote address + * @param[out] allAttributes all the attributes bits for that remote address + * + * @return true if the secure endpoint has been found, false otherwise. + */ +bool GetCASecureEndpointAttributes(const CAEndpoint_t* peer, uint32_t* allAttributes) +{ + bool result = false; + + OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s(peer = %s:%u)", __func__, + peer->addr, (uint32_t)peer->port); + + oc_mutex_lock(g_sslContextMutex); + + if (NULL == g_caSslContext) + { + OIC_LOG(ERROR, NET_SSL_TAG, "Context is NULL"); + } + else + { + SslEndPoint_t* sslPeer = GetSslPeer(peer); + + if (!sslPeer) + { + OIC_LOG(ERROR, NET_SSL_TAG, "SSL peer not found"); + } + else + { + *allAttributes = sslPeer->sep.attributes; + result = true; + } + } + + oc_mutex_unlock(g_sslContextMutex); + + OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s -> %s, attributes = %#x", __func__, + result ? "success" : "failed", result ? *allAttributes : 0); + return result; +} + +/** * Deletes cached message. * * @param[in] msg message @@ -1792,9 +1877,9 @@ static void SendCacheMessages(SslEndPoint_t * tep) void CAsetSslHandshakeCallback(CAErrorCallback tlsHandshakeCallback) { - OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__); + OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s(%p)", __func__, tlsHandshakeCallback); g_sslCallback = tlsHandshakeCallback; - OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__); + OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s(%p)", __func__, tlsHandshakeCallback); } /* Read data from TLS connection diff --git a/resource/csdk/connectivity/src/caconnectivitymanager.c b/resource/csdk/connectivity/src/caconnectivitymanager.c index b0bd2e9..b2e680c 100644 --- a/resource/csdk/connectivity/src/caconnectivitymanager.c +++ b/resource/csdk/connectivity/src/caconnectivitymanager.c @@ -155,6 +155,42 @@ const CASecureEndpoint_t *CAGetSecureEndpointData(const CAEndpoint_t *peer) } #endif //MULTIPLE_OWNER +bool CASetSecureEndpointAttribute(const CAEndpoint_t* peer, uint32_t attribute) +{ + bool success = false; + OIC_LOG_V(DEBUG, TAG, "In %s", __func__); + + if (!g_isInitialized) + { + OIC_LOG(DEBUG, TAG, "CA is not initialized"); + } + else + { + success = SetCASecureEndpointAttribute(peer, attribute); + } + + OIC_LOG_V(DEBUG, TAG, "Out %s -> %u", __func__, (uint32_t)success); + return success; +} + +bool CAGetSecureEndpointAttributes(const CAEndpoint_t* peer, uint32_t* attributes) +{ + bool success = false; + OIC_LOG_V(DEBUG, TAG, "In %s", __func__); + + if (!g_isInitialized) + { + OIC_LOG(DEBUG, TAG, "CA is not initialized"); + } + else + { + success = GetCASecureEndpointAttributes(peer, attributes); + } + + OIC_LOG_V(DEBUG, TAG, "Out %s -> %u", __func__, (uint32_t)success); + return success; +} + CAResult_t CAregisterSslHandshakeCallback(CAErrorCallback tlsHandshakeCallback) { OIC_LOG(DEBUG, TAG, "CAregisterSslHandshakeCallback"); diff --git a/resource/csdk/connectivity/test/ssladapter_test.cpp b/resource/csdk/connectivity/test/ssladapter_test.cpp index 7dd65ca..15fec8c 100644 --- a/resource/csdk/connectivity/test/ssladapter_test.cpp +++ b/resource/csdk/connectivity/test/ssladapter_test.cpp @@ -37,6 +37,8 @@ #ifdef MULTIPLE_OWNER #define GetCASecureEndpointData GetCASecureEndpointDataTest #endif +#define SetCASecureEndpointAttribute SetCASecureEndpointAttributeTest +#define GetCASecureEndpointAttributes GetCASecureEndpointAttributesTest #include "../src/adapter_util/ca_adapter_net_ssl.c" diff --git a/resource/csdk/security/provisioning/include/pmtypes.h b/resource/csdk/security/provisioning/include/pmtypes.h index 8581cc0..a1f8fb6 100644 --- a/resource/csdk/security/provisioning/include/pmtypes.h +++ b/resource/csdk/security/provisioning/include/pmtypes.h @@ -70,9 +70,10 @@ typedef struct OCProvisionDev #ifdef WITH_TCP uint16_t tcpPort; /**< tcp port **/ #endif - char secVer[OIC_SEC_MAX_VER_LEN]; /**< security version **/ + char secVer[OIC_SEC_MAX_VER_LEN]; /**< security version **/ DeviceStatus devStatus; /**< status of device **/ - OCDoHandle handle; + OCDoHandle handle; + bool ownerAclUnauthorizedRequest; /**< true if the provisioning client has already re-tried posting the Owner ACE **/ struct OCProvisionDev *next; /**< Next pointer. **/ }OCProvisionDev_t; diff --git a/resource/csdk/security/provisioning/src/ownershiptransfermanager.c b/resource/csdk/security/provisioning/src/ownershiptransfermanager.c index c0d94f8..51b7812 100755 --- a/resource/csdk/security/provisioning/src/ownershiptransfermanager.c +++ b/resource/csdk/security/provisioning/src/ownershiptransfermanager.c @@ -1144,27 +1144,24 @@ static OCStackApplicationResult OwnerCredentialHandler(void *ctx, OCDoHandle UNU if(OC_STACK_RESOURCE_CHANGED == clientResponse->result) { - if(otmCtx && otmCtx->selectedDeviceInfo) + if(otmCtx->selectedDeviceInfo) { - //Close the temporal secure session to verify the owner credential + //For Servers based on OCF 1.0, PostOwnerAcl can be executed using + //the already-existing session. However, get ready here to use the + //Owner Credential for establishing future secure sessions. + // + //For Servers based on OIC 1.1, PostOwnerAcl might fail with status + //OC_STACK_UNAUTHORIZED_REQ. After such a failure, OwnerAclHandler + //will close the current session and re-establish a new session, + //using the Owner Credential. CAEndpoint_t* endpoint = (CAEndpoint_t *)&otmCtx->selectedDeviceInfo->endpoint; - endpoint->port = otmCtx->selectedDeviceInfo->securePort; - CAResult_t caResult = CA_STATUS_OK; - caResult = CAcloseSslConnection(endpoint); - - if(CA_STATUS_OK != caResult) - { - OIC_LOG(ERROR, TAG, "Failed to close DTLS session"); - SetResult(otmCtx, caResult); - return OC_STACK_DELETE_TRANSACTION; - } /** - * If we select NULL cipher, - * client will select appropriate cipher suite according to server's cipher-suite list. - */ - // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256 = 0xC037, /**< see RFC 5489 */ - caResult = CASelectCipherSuite(0xC037, endpoint->adapter); + * If we select NULL cipher, + * client will select appropriate cipher suite according to server's cipher-suite list. + */ + // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256 = 0xC037, /**< see RFC 5489 */ + CAResult_t caResult = CASelectCipherSuite(0xC037, endpoint->adapter); if(CA_STATUS_OK != caResult) { OIC_LOG(ERROR, TAG, "Failed to select TLS_NULL_WITH_NULL_NULL"); @@ -1173,9 +1170,9 @@ static OCStackApplicationResult OwnerCredentialHandler(void *ctx, OCDoHandle UNU } /** - * in case of random PIN based OxM, - * revert get_psk_info callback of tinyDTLS to use owner credential. - */ + * in case of random PIN based OxM, + * revert get_psk_info callback of tinyDTLS to use owner credential. + */ if(OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel) { OicUuid_t emptyUuid = { .id={0}}; @@ -1232,26 +1229,57 @@ static OCStackApplicationResult OwnerAclHandler(void *ctx, OCDoHandle UNUSED, OIC_LOG(DEBUG, TAG, "IN OwnerAclHandler"); (void)UNUSED; - OCStackResult res = OC_STACK_OK; + OCStackResult res = clientResponse->result; OTMContext_t* otmCtx = (OTMContext_t*)ctx; otmCtx->ocDoHandle = NULL; + OCProvisionDev_t* selectedDeviceInfo = otmCtx->selectedDeviceInfo; - if(OC_STACK_RESOURCE_CHANGED == clientResponse->result) + if(OC_STACK_RESOURCE_CHANGED == res) { - if(otmCtx && otmCtx->selectedDeviceInfo) + if(NULL != selectedDeviceInfo) { //POST /oic/sec/doxm [{ ..., "owned":"TRUE" }] res = PostOwnershipInformation(otmCtx); if(OC_STACK_OK != res) { - OIC_LOG(ERROR, TAG, "Failed to update ownership information to new device"); + OIC_LOG_V(ERROR, TAG, "%s: Failed to update the ownership information of the new device, res = %d", + __func__, res); + SetResult(otmCtx, res); + } + } + } + else if((OC_STACK_UNAUTHORIZED_REQ == res) && + (NULL != selectedDeviceInfo) && + !selectedDeviceInfo->ownerAclUnauthorizedRequest) + { + OIC_LOG_V(WARNING, TAG, "%s: UNAUTHORIZED_REQ. Assuming server is based on OIC 1.1", + __func__); + selectedDeviceInfo->ownerAclUnauthorizedRequest = true; + + //Close the temporal secure session and re-connect using the owner credential + CAEndpoint_t* endpoint = (CAEndpoint_t *)&selectedDeviceInfo->endpoint; + endpoint->port = selectedDeviceInfo->securePort; + CAResult_t caResult = CAcloseSslConnection(endpoint); + + if(CA_STATUS_OK != caResult) + { + OIC_LOG_V(ERROR, TAG, "%s: Failed to close DTLS session, caResult = %d", + __func__, caResult); + SetResult(otmCtx, caResult); + } + else + { + res = PostOwnerAcl(otmCtx); + if(OC_STACK_OK != res) + { + OIC_LOG_V(ERROR, TAG, "%s: Failed to update owner ACL to new device, res = %d", + __func__, res); SetResult(otmCtx, res); } } } else { - res = clientResponse->result; OIC_LOG_V(ERROR, TAG, "OwnerAclHandler : Unexpected result %d", res); SetResult(otmCtx, res); } diff --git a/resource/csdk/security/src/doxmresource.c b/resource/csdk/security/src/doxmresource.c index 8464364..5da4598 100644 --- a/resource/csdk/security/src/doxmresource.c +++ b/resource/csdk/security/src/doxmresource.c @@ -18,6 +18,7 @@ // //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #include "iotivity_config.h" +#include "iotivity_debug.h" #include #include @@ -1001,6 +1002,30 @@ static bool ValidateOxmsel(const OicSecOxm_t *supportedMethods, return isValidOxmsel; } +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) +static void DoxmDTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info) +{ + OIC_LOG_V(DEBUG, TAG, "In %s(%p, %p)", __func__, endpoint, info); + + if ((NULL != endpoint) && (NULL != info) && (CA_STATUS_OK == info->result)) + { + /* + * Allow this OBT endpoint to bypass ACE checks for SVRs, while this + * device is not yet owned. + */ + OC_VERIFY(CASetSecureEndpointAttribute(endpoint, + CA_SECURE_ENDPOINT_ATTRIBUTE_ADMINISTRATOR)); + } + + OIC_LOG_V(DEBUG, TAG, "Out %s(%p, %p)", __func__, endpoint, info); +} + +static void RegisterOTMSslHandshakeCallback(CAErrorCallback callback) +{ + OC_VERIFY(CA_STATUS_OK == CAregisterSslHandshakeCallback(callback)); +} +#endif // __WITH_DTLS__ or __WITH_TLS__ + static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRequest) { OIC_LOG (DEBUG, TAG, "Doxm EntityHandle processing POST request"); @@ -1068,6 +1093,7 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR); OIC_LOG(INFO, TAG, "ECDH_ANON CipherSuite is DISABLED"); + RegisterOTMSslHandshakeCallback(DoxmDTLSHandshakeCB); caRes = CASelectCipherSuite((uint16_t)TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256, ehRequest->devAddr.adapter); VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR); OIC_LOG(INFO, TAG, "ECDHE_PSK CipherSuite will be used for MOT"); @@ -1163,8 +1189,9 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe ehRet = OC_EH_ERROR; goto exit; } - OIC_LOG (INFO, TAG, "Doxm EntityHandle enabling AnonECDHCipherSuite"); #if defined(__WITH_DTLS__) || defined(__WITH_TLS__) + RegisterOTMSslHandshakeCallback(DoxmDTLSHandshakeCB); + OIC_LOG(INFO, TAG, "Doxm EntityHandle enabling AnonECDHCipherSuite"); ehRet = (CAEnableAnonECDHCipherSuite(true) == CA_STATUS_OK) ? OC_EH_OK : OC_EH_ERROR; #endif // __WITH_DTLS__ or __WITH_TLS__ goto exit; @@ -1191,6 +1218,7 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe * Disable anonymous ECDH cipher in tinyDTLS since device is now * in owned state. */ + RegisterOTMSslHandshakeCallback(NULL); CAResult_t caRes = CA_STATUS_OK; caRes = CAEnableAnonECDHCipherSuite(false); VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR); @@ -1252,8 +1280,8 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe { /* * If current state of the device is un-owned, enable - * anonymous ECDH cipher in tinyDTLS so that Provisioning - * tool can initiate JUST_WORKS ownership transfer process. + * ECDHE_PSK cipher so that the Provisioning tool can + * initiate the ownership transfer. */ if(memcmp(&(newDoxm->owner), &emptyOwner, sizeof(OicUuid_t)) == 0) { @@ -1270,12 +1298,11 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe } #if defined(__WITH_DTLS__) || defined(__WITH_TLS__) - CAResult_t caRes = CA_STATUS_OK; - - caRes = CAEnableAnonECDHCipherSuite(false); + CAResult_t caRes = CAEnableAnonECDHCipherSuite(false); VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR); OIC_LOG(INFO, TAG, "ECDH_ANON CipherSuite is DISABLED"); + RegisterOTMSslHandshakeCallback(DoxmDTLSHandshakeCB); caRes = CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256, ehRequest->devAddr.adapter); VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR); @@ -1356,6 +1383,8 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe OIC_LOG(WARNING, TAG, "Failed to update DOXM in persistent storage"); ehRet = OC_EH_ERROR; } + + RegisterOTMSslHandshakeCallback(NULL); CAResult_t caRes = CAEnableAnonECDHCipherSuite(false); VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR); OIC_LOG(INFO, TAG, "ECDH_ANON CipherSuite is DISABLED"); @@ -1674,6 +1703,7 @@ static void PrepareMOT(const OicSecDoxm_t* doxm) VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR); OIC_LOG(INFO, TAG, "ECDH_ANON CipherSuite is DISABLED"); + RegisterOTMSslHandshakeCallback(DoxmDTLSHandshakeCB); caRes = CASelectCipherSuite((uint16_t)TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256, CA_ADAPTER_IP); VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR); #ifdef __WITH_TLS__ diff --git a/resource/csdk/security/src/policyengine.c b/resource/csdk/security/src/policyengine.c index bd67af3..e217608 100644 --- a/resource/csdk/security/src/policyengine.c +++ b/resource/csdk/security/src/policyengine.c @@ -106,19 +106,31 @@ static bool IsRequestFromDevOwner(SRMRequestContext_t *context) return retVal; } - /* - if(OC_STACK_OK == GetDoxmDevOwnerId(&ownerid)) - { - retVal = UuidCmp(&context->subject, &ownerid); - } - */ - - // TODO: Added as workaround for CTT OicSecDoxm_t* doxm = (OicSecDoxm_t*) GetDoxmResourceData(); if (doxm) { retVal = UuidCmp(&doxm->owner, &context->subjectUuid); + OIC_LOG_V(DEBUG, TAG, "%s: request was %sreceived from device owner", + __func__, retVal ? "" : "NOT "); } + +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) + //Ownership Transfer sessions are allowed to bypass SVR ACEs, while this + //Device is not owned yet. + if (!retVal && (NULL != context->endPoint)) + { + uint32_t allAttributes; + if (CAGetSecureEndpointAttributes(context->endPoint, &allAttributes) && + (allAttributes & CA_SECURE_ENDPOINT_ATTRIBUTE_ADMINISTRATOR)) + { + retVal = true; + } + + OIC_LOG_V(DEBUG, TAG, "%s: request was %sreceived from Ownership Transfer session", + __func__, retVal ? "" : "NOT "); + } +#endif + return retVal; }