X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=resource%2Fcsdk%2Fsecurity%2Fsrc%2Fsrmutility.c;h=2bd9bcd2461798a4b40f6900b510a8c81f904fe9;hb=c315c87e07c4080ecd0ef488e7a1047bc3c509b2;hp=1a745b8800c72ab8da69ad1b99b78bec069d1923;hpb=3e08f0b76cfa2aebd58a6acd4d8a6ae64c5d3cf4;p=platform%2Fupstream%2Fiotivity.git diff --git a/resource/csdk/security/src/srmutility.c b/resource/csdk/security/src/srmutility.c index 1a745b8..2bd9bcd 100644 --- a/resource/csdk/security/src/srmutility.c +++ b/resource/csdk/security/src/srmutility.c @@ -24,57 +24,53 @@ #include "srmresourcestrings.h" #include "logger.h" #include "oic_malloc.h" +#include "oic_string.h" #include "base64.h" +#include "doxmresource.h" +#include "pstatresource.h" +#include "cacommon.h" +#include "casecurityinterface.h" +#if defined(__WITH_DTLS__) || defined (__WITH_TLS__) +#include "pkix_interface.h" +#endif -#define TAG "SRM-UTILITY" +#define TAG "OIC_SRM_UTILITY" -/** - * This method initializes the OicParseQueryIter_t struct - * - *@param query - REST query, to be parsed - *@param parseIter - OicParseQueryIter_t struct, to be initialized - * - */ -void ParseQueryIterInit(unsigned char * query, OicParseQueryIter_t * parseIter) +void ParseQueryIterInit(const unsigned char * query, OicParseQueryIter_t * parseIter) { - OIC_LOG (INFO, TAG, "Initializing coap iterator"); - if((NULL == query) || (NULL == parseIter)) + OIC_LOG(INFO, TAG, "Initializing coap iterator"); + if ((NULL == query) || (NULL == parseIter)) + { return; + } parseIter->attrPos = NULL; parseIter->attrLen = 0; parseIter->valPos = NULL; parseIter->valLen = 0; - coap_parse_iterator_init(query, strlen((char *)query), - (unsigned char *)OIC_SEC_REST_QUERY_SEPARATOR, (unsigned char *) "", 0, &parseIter->pi); + coap_parse_iterator_init((unsigned char *)query, strlen((char *)query), + (unsigned char *)OIC_SEC_REST_QUERY_SEPARATOR, + (unsigned char *) "", 0, &parseIter->pi); } -/** - * This method fills the OicParseQueryIter_t struct with next REST query's - * attribute's and value's information - * - *@param parseIter - OicParseQueryIter_t struct, has next query's attribute's & value's info - * - * @retval - * OicParseQueryIter_t * - has parsed query info - * NULL - has no query to parse - */ OicParseQueryIter_t * GetNextQuery(OicParseQueryIter_t * parseIter) { - OIC_LOG (INFO, TAG, "Getting Next Query"); - if(NULL == parseIter) + OIC_LOG(INFO, TAG, "Getting Next Query"); + if (NULL == parseIter) + { return NULL; + } unsigned char * qrySeg = NULL; char * delimPos; - //Get the next query. Querys are separated by OIC_SEC_REST_QUERY_SEPARATOR + // Get the next query. Querys are separated by OIC_SEC_REST_QUERY_SEPARATOR. qrySeg = coap_parse_next(&parseIter->pi); - if(qrySeg) + if (qrySeg) { delimPos = strchr((char *)qrySeg, OIC_SEC_REST_QUERY_DELIMETER); - if(delimPos) + if (delimPos) { parseIter->attrPos = parseIter->pi.pos; parseIter->attrLen = (unsigned char *)delimPos - parseIter->pi.pos; @@ -86,26 +82,25 @@ OicParseQueryIter_t * GetNextQuery(OicParseQueryIter_t * parseIter) return NULL; } - // TODO This functionality is replicated in all SVR's and therefore we need // to encapsulate it in a common method. However, this may not be the right // file for this method. -OCStackResult AddUuidArray(cJSON* jsonRoot, const char* arrayItem, - size_t *numUuids, OicUuid_t** uuids ) +OCStackResult AddUuidArray(const cJSON* jsonRoot, const char* arrayItem, + size_t *numUuids, OicUuid_t** uuids) { size_t idxx = 0; - cJSON* jsonObj = cJSON_GetObjectItem(jsonRoot, arrayItem); + cJSON* jsonObj = cJSON_GetObjectItem((cJSON *)jsonRoot, arrayItem); VERIFY_NON_NULL(TAG, jsonObj, ERROR); VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR); - *numUuids = cJSON_GetArraySize(jsonObj); + *numUuids = (size_t)cJSON_GetArraySize(jsonObj); VERIFY_SUCCESS(TAG, *numUuids > 0, ERROR); *uuids = (OicUuid_t*)OICCalloc(*numUuids, sizeof(OicUuid_t)); VERIFY_NON_NULL(TAG, *uuids, ERROR); do { - unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {}; + unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {0}; uint32_t outLen = 0; B64Result b64Ret = B64_OK; @@ -115,10 +110,10 @@ OCStackResult AddUuidArray(cJSON* jsonRoot, const char* arrayItem, outLen = 0; b64Ret = b64Decode(jsonOwnr->valuestring, strlen(jsonOwnr->valuestring), base64Buff, - sizeof(base64Buff), &outLen); + sizeof(base64Buff), &outLen); VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof((*uuids)[idxx].id)), - ERROR); + ERROR); memcpy((*uuids)[idxx].id, base64Buff, outLen); } while ( ++idxx < *numUuids); @@ -128,3 +123,255 @@ exit: return OC_STACK_ERROR; } + +/** + * Function to getting string of ownership transfer method + * + * @prarm oxmType ownership transfer method + * + * @return string value of ownership transfer method + */ +const char* GetOxmString(OicSecOxm_t oxmType) +{ + switch(oxmType) + { + case OIC_JUST_WORKS: + return OXM_JUST_WORKS; + case OIC_RANDOM_DEVICE_PIN: + return OXM_RANDOM_DEVICE_PIN; + case OIC_MANUFACTURER_CERTIFICATE: + return OXM_MANUFACTURER_CERTIFICATE; +#ifdef MULTIPLE_OWNER + case OIC_PRECONFIG_PIN: + return OXM_PRECONF_PIN; +#endif //MULTIPLE_OWNER + case OIC_MV_JUST_WORKS: + return OXM_MV_JUST_WORKS; + case OIC_CON_MFG_CERT: + return OXM_CON_MFG_CERT; + default: + return NULL; + } +} + +OCStackResult ConvertUuidToStr(const OicUuid_t* uuid, char** strUuid) +{ + if(NULL == uuid || NULL == strUuid || NULL != *strUuid) + { + OIC_LOG(ERROR, TAG, "ConvertUuidToStr : Invalid param"); + return OC_STACK_INVALID_PARAM; + } + + size_t uuidIdx = 0; + size_t urnIdx = 0; + const size_t urnBufSize = (UUID_LENGTH * 2) + 4 + 1; + char* convertedUrn = (char*)OICCalloc(urnBufSize, sizeof(char)); + VERIFY_NON_NULL(TAG, convertedUrn, ERROR); + + for(uuidIdx=0, urnIdx=0; uuidIdx < UUID_LENGTH && urnIdx < urnBufSize; uuidIdx++, urnIdx+=2) + { + // canonical format for UUID has '8-4-4-4-12' + if(uuidIdx==4 || uuidIdx==6 || uuidIdx==8 || uuidIdx==10) + { + snprintf(convertedUrn + urnIdx, 2, "%c", '-'); + urnIdx++; + } + snprintf(convertedUrn + urnIdx, 3, "%02x", (uint8_t)(uuid->id[uuidIdx])); + } + convertedUrn[urnBufSize - 1] = '\0'; + + *strUuid = convertedUrn; + return OC_STACK_OK; + +exit: + return OC_STACK_NO_MEMORY; +} + +OCStackResult ConvertStrToUuid(const char* strUuid, OicUuid_t* uuid) +{ + if(NULL == strUuid || NULL == uuid) + { + OIC_LOG(ERROR, TAG, "ConvertStrToUuid : Invalid param"); + return OC_STACK_INVALID_PARAM; + } + + size_t urnIdx = 0; + size_t uuidIdx = 0; + size_t strUuidLen = 0; + char convertedUuid[UUID_LENGTH * 2] = {0}; + + strUuidLen = strlen(strUuid); + if(0 == strUuidLen) + { + OIC_LOG(INFO, TAG, "The empty string detected, The UUID will be converted to "\ + "\"00000000-0000-0000-0000-000000000000\""); + } + else if(UUID_LENGTH * 2 + 4 == strUuidLen) + { + for(uuidIdx=0, urnIdx=0; uuidIdx < UUID_LENGTH ; uuidIdx++, urnIdx+=2) + { + if(*(strUuid + urnIdx) == '-') + { + urnIdx++; + } + sscanf(strUuid + urnIdx, "%2hhx", &convertedUuid[uuidIdx]); + } + } + else + { + OIC_LOG(ERROR, TAG, "Invalid string uuid format, Please set the uuid as correct format"); + OIC_LOG(ERROR, TAG, "e.g) \"72616E64-5069-6E44-6576-557569643030\" (4-2-2-2-6)"); + OIC_LOG(ERROR, TAG, "e.g) \"\""); + + return OC_STACK_INVALID_PARAM; + } + + memcpy(uuid->id, convertedUuid, UUID_LENGTH); + + return OC_STACK_OK; +} + +#if defined(__WITH_DTLS__) || defined (__WITH_TLS__) +OCStackResult SetDeviceIdSeed(const uint8_t* seed, size_t seedSize) +{ + return SetDoxmDeviceIDSeed(seed, seedSize); +} + +static OicSecOtmEventHandler_t gOtmEventHandler = NULL; +static char ptAddr[256] = {0}; +static uint16_t ptPort = 0; + +void SetOtmEventHandler(OicSecOtmEventHandler_t otmEventHandler) +{ + OIC_LOG_V(DEBUG, TAG, "In %s", __func__); + + memset(ptAddr, 0x00, sizeof(ptAddr)); + ptPort = 0; + gOtmEventHandler = otmEventHandler; + OIC_LOG_V(DEBUG, TAG, "Out%s", __func__); +} + +/** + * Function to handle the handshake result in OTM. + * This function will be invoked after DTLS handshake + * @param endPoint [IN] The remote endpoint. + * @param errorInfo [IN] Error information from the endpoint. + * @return NONE + */ +static void DTLSHandshakeServerCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info) +{ + OIC_LOG_V(DEBUG, TAG, "In %s", __func__); + if(NULL != endpoint && NULL != info) + { + OIC_LOG_V(INFO, TAG, "Received status from remote device(%s:%d) : %d", + endpoint->addr, endpoint->port, info->result); + + //We can't know about PT's secure port, so compare only adress to identify the PT. + if (strncmp(endpoint->addr, ptAddr, strlen(ptAddr)) == 0) + { + OIC_LOG_V(INFO, TAG, "Normal port is [%s:%d]", ptAddr, ptPort); + + //If DTLS handshake error occurred, revert secure resource and notify error event to application. + if (CA_STATUS_OK != info->result) + { + OIC_LOG(ERROR, TAG, "Failed to establish a secure session with owner device."); + OIC_LOG(ERROR, TAG, "Doxm/Pstat resource will be reverted to init state."); + RestoreDoxmToInitState(); + RestorePstatToInitState(); + InvokeOtmEventHandler(endpoint->addr, endpoint->port, NULL, OIC_OTM_ERROR); + } + } + else + { + OIC_LOG_V(WARNING, TAG, "[%s:%d] is not a owner device", endpoint->addr, endpoint->port); + } + } + else + { + OIC_LOG(WARNING, TAG, "Invalid param."); + } + OIC_LOG_V(DEBUG, TAG, "Out %s", __func__); +} + + +void InvokeOtmEventHandler(const char* addr, uint16_t port, + const OicUuid_t* uuid, OicSecOtmEvent_t event) +{ + char* strUuid = NULL; + OIC_LOG_V(DEBUG, TAG, "In %s", __func__); + + //addr can be NULL for init state + //port can be '0' for BLE and init state + //uuid can be NULL for init state & coap + + switch(event) + { + case OIC_OTM_READY: + case OIC_OTM_STARTED: + if (addr) + { + OICStrcpy(ptAddr, sizeof(ptAddr), addr); + ptPort = port; + } + else + { + memset(ptAddr, 0x00, sizeof(ptAddr)); + ptPort = 0; + } + //Register TLS event handler to catch the tls event while handshake + if(CA_STATUS_OK != CAregisterSslHandshakeCallback(DTLSHandshakeServerCB)) + { + OIC_LOG(WARNING, TAG, "Failed to register (D)TLS handshake callback."); + } + break; + case OIC_OTM_DONE: + case OIC_OTM_ERROR: + memset(ptAddr, 0x00, sizeof(ptAddr)); + ptPort = 0; + //Register TLS event handler to catch the tls event while handshake + if(CA_STATUS_OK != CAregisterSslHandshakeCallback(NULL)) + { + OIC_LOG(WARNING, TAG, "Failed to register (D)TLS handshake callback."); + } + //Restore Pkix handler to initial state + CAregisterPkixInfoHandler(GetPkixInfo); + CAregisterGetCredentialTypesHandler(InitCipherSuiteList); + break; + default: + OIC_LOG_V(ERROR, TAG, "Unknow OTM event : %d", event); + goto exit; + } + + if (uuid) + { + if(OC_STACK_OK != ConvertUuidToStr(uuid, &strUuid)) + { + OIC_LOG(ERROR, TAG, "Failed to convert UUID to String."); + goto exit; + } + } + + OIC_LOG(DEBUG, TAG, "================================="); + OIC_LOG(DEBUG, TAG, "[OTM Event]"); + OIC_LOG_V(DEBUG, TAG, "PT UUID : %s", (strUuid ? strUuid : "NULL")); + OIC_LOG_V(DEBUG, TAG, "PT Addr=%s:%d", (addr ? addr : "NULL"), port); + OIC_LOG_V(DEBUG, TAG, "Event Code=%d", event); + OIC_LOG(DEBUG, TAG, "================================="); + + if (NULL == gOtmEventHandler) + { + OIC_LOG(WARNING, TAG, "OTM event handler is not registered."); + goto exit; + } + + OIC_LOG(DEBUG, TAG, "Invoking callback to notify OTM state.."); + gOtmEventHandler(addr, port, strUuid, (int)event); + +exit: + if (strUuid) + { + OICFree(strUuid); + } + OIC_LOG_V(DEBUG, TAG, "Out %s", __func__); +} +#endif