char * BinToPstatJSON(const OicSecPstat_t * pstat, const bool isIncResName) { if(NULL == pstat) { return NULL; } cJSON *jsonPstat = NULL; char *jsonStr = NULL; cJSON *jsonSmArray = NULL; char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*) 0)->id)) + 1] = {}; uint32_t outLen = 0; B64Result b64Ret = B64_OK; cJSON *jsonRoot = NULL; if(isIncResName) { jsonRoot = cJSON_CreateObject(); VERIFY_NON_NULL(TAG, jsonRoot, INFO); cJSON_AddItemToObject(jsonRoot, OIC_JSON_PSTAT_NAME, jsonPstat = cJSON_CreateObject()); } else { jsonPstat = cJSON_CreateObject(); jsonRoot = jsonPstat; } VERIFY_NON_NULL(TAG, jsonPstat, INFO); cJSON_AddBoolToObject(jsonPstat, OIC_JSON_ISOP_NAME, pstat->isOp); b64Ret = b64Encode(pstat->deviceID.id, sizeof(pstat->deviceID.id), base64Buff, sizeof(base64Buff), &outLen); VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR); cJSON_AddStringToObject(jsonPstat, OIC_JSON_DEVICE_ID_NAME, base64Buff); cJSON_AddNumberToObject(jsonPstat, OIC_JSON_COMMIT_HASH_NAME, pstat->commitHash); cJSON_AddNumberToObject(jsonPstat, OIC_JSON_CM_NAME, (int)pstat->cm); cJSON_AddNumberToObject(jsonPstat, OIC_JSON_TM_NAME, (int)pstat->tm); cJSON_AddNumberToObject(jsonPstat, OIC_JSON_OM_NAME, (int)pstat->om); cJSON_AddItemToObject(jsonPstat, OIC_JSON_SM_NAME, jsonSmArray = cJSON_CreateArray()); VERIFY_NON_NULL(TAG, jsonSmArray, INFO); for (size_t i = 0; i < pstat->smLen; i++) { cJSON_AddItemToArray(jsonSmArray, cJSON_CreateNumber((int )pstat->sm[i])); } jsonStr = cJSON_Print(jsonRoot); exit: if (jsonRoot) { cJSON_Delete(jsonRoot); } return jsonStr; }
std::string OCSecureResource::getDeviceID() { char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {0,}; uint32_t outLen = 0; B64Result b64Ret = B64_OK; std::ostringstream deviceId(""); validateSecureResource(); b64Ret = b64Encode(devPtr->doxm->deviceID.id, sizeof(devPtr->doxm->deviceID.id), base64Buff, sizeof(base64Buff), &outLen); if (B64_OK == b64Ret) { deviceId << base64Buff; } return deviceId.str(); }
OCStackResult SendAclReq(PEContext_t *context, OCDevAddr *devAddr, OCConnectivityType connType, uint16_t securedPort) { OCStackResult ret = OC_STACK_ERROR; const char GET_ACE_QUERY_FMT[] = "%s?%s=%s;%s=%s"; char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {}; uint32_t outLen = 0; char uri[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {}; OCCallbackData cbData = {.context=NULL}; OCDevAddr destAddr = {.adapter = OC_ADAPTER_IP}; B64Result b64Ret; VERIFY_NON_NULL(TAG, context, ERROR); VERIFY_NON_NULL(TAG, devAddr, ERROR); b64Ret = b64Encode(context->subject.id, sizeof(context->subject.id), base64Buff, sizeof(base64Buff), &outLen); VERIFY_SUCCESS(TAG, B64_OK == b64Ret, ERROR); snprintf(uri, sizeof(uri), GET_ACE_QUERY_FMT, OIC_RSRC_ACL_URI, OIC_JSON_SUBJECT_NAME, base64Buff, OIC_JSON_RESOURCES_NAME, context->resource); cbData.cb = &AmsMgrAclReqCallback; cbData.context = context; destAddr = *devAddr; //update port info destAddr.flags = (OCTransportFlags)(destAddr.flags | OC_FLAG_SECURE); destAddr.port = securedPort; OC_LOG_V(INFO, TAG, "AMS Manager Sending Unicast ACL request with URI = %s", uri); ret = OCDoResource(NULL, OC_REST_GET, uri, &destAddr, NULL, connType, OC_LOW_QOS, &cbData, NULL, 0); exit: OC_LOG_V(INFO, TAG, "%s returns %d ", __func__, ret); return ret; }
/* * Generating new credential for provisioning tool * * PSK generated by */ static OCEntityHandlerResult AddOwnerPSK(const CAEndpoint_t* endpoint, OicSecDoxm_t* ptDoxm, const uint8_t* label, const size_t labelLen) { size_t ownLen = 1; uint32_t outLen = 0; OicSecCred_t *cred = NULL; uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {}; CAResult_t pskRet = CAGenerateOwnerPSK(endpoint, label, labelLen, ptDoxm->owner.id, sizeof(ptDoxm->owner.id), gDoxm->deviceID.id, sizeof(gDoxm->deviceID.id), ownerPSK, OWNER_PSK_LENGTH_128); VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR); char base64Buff[B64ENCODE_OUT_SAFESIZE(OWNER_PSK_LENGTH_128) + 1] = {}; B64Result b64Ret = b64Encode(ownerPSK, OWNER_PSK_LENGTH_128, base64Buff, sizeof(base64Buff), &outLen); VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR); OIC_LOG (DEBUG, TAG, "Doxm EntityHandle generating Credential"); cred = GenerateCredential(&ptDoxm->owner, SYMMETRIC_PAIR_WISE_KEY, NULL, base64Buff, ownLen, &ptDoxm->owner); VERIFY_NON_NULL(TAG, cred, ERROR); //Adding provisioning tool credential to cred Resource. VERIFY_SUCCESS(TAG, OC_STACK_OK == AddCredential(cred), ERROR); gDoxm->owned = true; gDoxm->oxmSel = ptDoxm->oxmSel; memcpy(&(gDoxm->owner), &(ptDoxm->owner), sizeof(OicUuid_t)); return OC_EH_OK; exit: return OC_EH_ERROR; }
OCStackResult DiscoverAmsService(PEContext_t *context) { OC_LOG(INFO, TAG, "IN DiscoverAmsService"); OCStackResult ret = OC_STACK_ERROR; const char DOXM_DEVICEID_QUERY_FMT[] = "%s?%s=%s"; char uri[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {}; OCCallbackData cbData = {.context=NULL}; char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {}; uint32_t outLen = 0; B64Result b64Ret; VERIFY_NON_NULL(TAG, context, ERROR); b64Ret = b64Encode(context->amsMgrContext->amsDeviceId.id, sizeof(context->amsMgrContext->amsDeviceId.id), base64Buff, sizeof(base64Buff), &outLen); VERIFY_SUCCESS(TAG, B64_OK == b64Ret, ERROR); snprintf(uri, sizeof(uri), DOXM_DEVICEID_QUERY_FMT, OIC_RSRC_DOXM_URI, OIC_JSON_DEVICE_ID_NAME, base64Buff); cbData.cb = &AmsMgrDiscoveryCallback; cbData.context = (void*)context; /* TODO * If no good response was received for this discovery request, * PE would be blocked forever waiting for AMS service to respond with the ACE. * Need logic to reset the PE state and send ACCESS_DENIED response, * when discovery response from AMS service is not received within certain time. */ OC_LOG_V(INFO, TAG,"AMS Manager Sending Multicast Discovery with URI = %s", uri); ret = OCDoResource(NULL, OC_REST_DISCOVER, uri, NULL, NULL, CT_DEFAULT, OC_LOW_QOS, &cbData, NULL, 0); exit: OC_LOG(INFO, TAG, "Leaving DiscoverAmsService"); return ret; }
/** * Function to save ownerPSK at provisioning tool end. * * @param[in] selectedDeviceInfo selected device information to performing provisioning. * @return OC_STACK_OK on success */ static OCStackResult SaveOwnerPSK(OCProvisionDev_t *selectedDeviceInfo) { OC_LOG(DEBUG, TAG, "IN SaveOwnerPSK"); OCStackResult res = OC_STACK_ERROR; CAEndpoint_t endpoint; memset(&endpoint, 0x00, sizeof(CAEndpoint_t)); OICStrcpy(endpoint.addr, MAX_ADDR_STR_SIZE_CA, selectedDeviceInfo->endpoint.addr); endpoint.addr[MAX_ADDR_STR_SIZE_CA - 1] = '\0'; endpoint.port = selectedDeviceInfo->securePort; OicUuid_t ptDeviceID = {.id={0}}; if (OC_STACK_OK != GetDoxmDeviceID(&ptDeviceID)) { OC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID"); return res; } uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0}; //Generating OwnerPSK CAResult_t pskRet = CAGenerateOwnerPSK(&endpoint, (uint8_t *)GetOxmString(selectedDeviceInfo->doxm->oxmSel), strlen(GetOxmString(selectedDeviceInfo->doxm->oxmSel)), ptDeviceID.id, sizeof(ptDeviceID.id), selectedDeviceInfo->doxm->deviceID.id, sizeof(selectedDeviceInfo->doxm->deviceID.id), ownerPSK, OWNER_PSK_LENGTH_128); if (CA_STATUS_OK == pskRet) { OC_LOG(INFO, TAG,"ownerPSK dump:\n"); OC_LOG_BUFFER(INFO, TAG,ownerPSK, OWNER_PSK_LENGTH_128); //Generating new credential for provisioning tool size_t ownLen = 1; uint32_t outLen = 0; char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(ownerPSK)) + 1] = {}; B64Result b64Ret = b64Encode(ownerPSK, sizeof(ownerPSK), base64Buff, sizeof(base64Buff), &outLen); VERIFY_SUCCESS(TAG, B64_OK == b64Ret, ERROR); OicSecCred_t *cred = GenerateCredential(&selectedDeviceInfo->doxm->deviceID, SYMMETRIC_PAIR_WISE_KEY, NULL, base64Buff, ownLen, &ptDeviceID); VERIFY_NON_NULL(TAG, cred, ERROR); res = AddCredential(cred); if(res != OC_STACK_OK) { DeleteCredList(cred); return res; } } else { OC_LOG(ERROR, TAG, "CAGenerateOwnerPSK failed"); } OC_LOG(DEBUG, TAG, "OUT SaveOwnerPSK"); exit: return res; }
char * BinToDoxmJSON(const OicSecDoxm_t * doxm) { if (NULL == doxm) { return NULL; } char *jsonStr = NULL; cJSON *jsonDoxm = NULL; char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {}; uint32_t outLen = 0; B64Result b64Ret = B64_OK; cJSON *jsonRoot = cJSON_CreateObject(); VERIFY_NON_NULL(TAG, jsonRoot, ERROR); jsonDoxm = cJSON_CreateObject(); VERIFY_NON_NULL(TAG, jsonDoxm, ERROR); cJSON_AddItemToObject(jsonRoot, OIC_JSON_DOXM_NAME, jsonDoxm ); //OxmType -- Not Mandatory if(doxm->oxmTypeLen > 0) { cJSON *jsonOxmTyArray = cJSON_CreateArray(); VERIFY_NON_NULL(TAG, jsonOxmTyArray, ERROR); cJSON_AddItemToObject (jsonDoxm, OIC_JSON_OXM_TYPE_NAME, jsonOxmTyArray ); for (size_t i = 0; i < doxm->oxmTypeLen; i++) { cJSON_AddItemToArray (jsonOxmTyArray, cJSON_CreateString(doxm->oxmType[i])); } } //Oxm -- Not Mandatory if(doxm->oxmLen > 0) { cJSON *jsonOxmArray = cJSON_CreateArray(); VERIFY_NON_NULL(TAG, jsonOxmArray, ERROR); cJSON_AddItemToObject (jsonDoxm, OIC_JSON_OXM_NAME,jsonOxmArray ); for (size_t i = 0; i < doxm->oxmLen; i++) { cJSON_AddItemToArray (jsonOxmArray, cJSON_CreateNumber(doxm->oxm[i])); } } //OxmSel -- Mandatory cJSON_AddNumberToObject(jsonDoxm, OIC_JSON_OXM_SEL_NAME, (int)doxm->oxmSel); //sct -- Mandatory cJSON_AddNumberToObject(jsonDoxm, OIC_JSON_SUPPORTED_CRED_TYPE_NAME, (int)doxm->sct); //Owned -- Mandatory cJSON_AddBoolToObject(jsonDoxm, OIC_JSON_OWNED_NAME, doxm->owned); //TODO: Need more clarification on deviceIDFormat field type. #if 0 //DeviceIdFormat -- Mandatory cJSON_AddNumberToObject(jsonDoxm, OIC_JSON_DEVICE_ID_FORMAT_NAME, doxm->deviceIDFormat); #endif //DeviceId -- Mandatory outLen = 0; b64Ret = b64Encode(doxm->deviceID.id, sizeof(doxm->deviceID.id), base64Buff, sizeof(base64Buff), &outLen); VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR); cJSON_AddStringToObject(jsonDoxm, OIC_JSON_DEVICE_ID_NAME, base64Buff); //DPC -- Mandatory cJSON_AddBoolToObject(jsonDoxm, OIC_JSON_DPC_NAME, doxm->dpc); //Owner -- Mandatory outLen = 0; b64Ret = b64Encode(doxm->owner.id, sizeof(doxm->owner.id), base64Buff, sizeof(base64Buff), &outLen); VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR); cJSON_AddStringToObject(jsonDoxm, OIC_JSON_OWNER_NAME, base64Buff); jsonStr = cJSON_PrintUnformatted(jsonRoot); exit: if (jsonRoot) { cJSON_Delete(jsonRoot); } return jsonStr; }
static OCEntityHandlerResult HandleDoxmPutRequest (const OCEntityHandlerRequest * ehRequest) { OC_LOG (INFO, TAG, PCF("Doxm EntityHandle processing PUT request")); OCEntityHandlerResult ehRet = OC_EH_ERROR; OicUuid_t emptyOwner = {.id = {0}}; /* * Convert JSON Doxm data into binary. This will also validate * the Doxm data received. */ OicSecDoxm_t* newDoxm = JSONToDoxmBin(((OCSecurityPayload*)ehRequest->payload)->securityData); if (newDoxm) { // Iotivity SRM ONLY supports OIC_JUST_WORKS now if (OIC_JUST_WORKS == newDoxm->oxmSel) { /* * 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. */ if ((false == gDoxm->owned) && (false == newDoxm->owned)) { OC_LOG (INFO, TAG, PCF("Doxm EntityHandle enabling AnonECDHCipherSuite")); #ifdef __WITH_DTLS__ ehRet = (CAEnableAnonECDHCipherSuite(true) == CA_STATUS_OK) ? OC_EH_OK : OC_EH_ERROR; #endif //__WITH_DTLS__ goto exit; } /* * When current state of the device is un-owned and Provisioning * Tool is attempting to change the state to 'Owned' with a * qualified value for the field 'Owner' */ if ((false == gDoxm->owned) && (true == newDoxm->owned) && (memcmp(&(newDoxm->owner), &emptyOwner, sizeof(OicUuid_t)) != 0)) { /* * Generate OwnerPSK and create credential for Provisioning * tool with the generated OwnerPSK. * Update persistent storage and disable anonymous ECDH cipher * */ #ifdef __WITH_DTLS__ CAResult_t pskRet; OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle; uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {}; //Generating OwnerPSK OC_LOG (INFO, TAG, PCF("Doxm EntityHandle generating OwnerPSK")); pskRet = CAGenerateOwnerPSK((CAEndpoint_t *)&request->devAddr, (uint8_t*) OXM_JUST_WORKS, strlen(OXM_JUST_WORKS), newDoxm->owner.id, sizeof(newDoxm->owner.id), gDoxm->deviceID.id, sizeof(gDoxm->deviceID.id), ownerPSK, OWNER_PSK_LENGTH_128); VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR); //Generating new credential for provisioning tool size_t ownLen = 1; uint32_t outLen = 0; char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(ownerPSK)) + 1] = {}; B64Result b64Ret = b64Encode(ownerPSK, sizeof(ownerPSK), base64Buff, sizeof(base64Buff), &outLen); VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR); OC_LOG (INFO, TAG, PCF("Doxm EntityHandle generating Credential")); OicSecCred_t *cred = GenerateCredential(&newDoxm->owner, SYMMETRIC_PAIR_WISE_KEY, NULL, base64Buff, ownLen, &newDoxm->owner); VERIFY_NON_NULL(TAG, cred, ERROR); //Adding provisioning tool credential to cred Resource. VERIFY_SUCCESS(TAG, OC_STACK_OK == AddCredential(cred), ERROR); gDoxm->owned = true; memcpy(&(gDoxm->owner), &(newDoxm->owner), sizeof(OicUuid_t)); // Update new state in persistent storage if (true == UpdatePersistentStorage(gDoxm)) { ehRet = OC_EH_OK; } else { ehRet = OC_EH_ERROR; /* * If persistent storage update failed, revert back the state * for global variable. */ gDoxm->owned = false; memset(&(gDoxm->owner), 0, sizeof(OicUuid_t)); } /* * Disable anonymous ECDH cipher in tinyDTLS since device is now * in owned state. */ CAEnableAnonECDHCipherSuite(false); #endif //__WITH_DTLS__ } } } exit: //Send payload to request originator if(OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL)) { OC_LOG (ERROR, TAG, PCF("SendSRMResponse failed in HandlePstatPostRequest")); } DeleteDoxmBinData(newDoxm); return ehRet; }