#include "cainterface.h"
#include "resourcemanager.h"
#include "credresource.h"
+#include "doxmresource.h"
+#include "pstatresource.h"
#include "policyengine.h"
#include "srmutility.h"
+#include "psinterface.h"
#include "amsmgr.h"
#include "oic_string.h"
#include "oic_malloc.h"
#include "securevirtualresourcetypes.h"
#include "secureresourcemanager.h"
#include "srmresourcestrings.h"
+#include "ocresourcehandler.h"
-#define TAG "SRM"
-
-#ifdef __WITH_X509__
-#include "crlresource.h"
-#endif // __WITH_X509__
+#if defined( __WITH_TLS__) || defined(__WITH_DTLS__)
+#include "pkix_interface.h"
+#endif //__WITH_TLS__ or __WITH_DTLS__
+#define TAG "OIC_SRM"
//Request Callback handler
static CARequestCallback gRequestHandler = NULL;
sizeof(responseInfo.info));
responseInfo.info.payload = NULL;
responseInfo.result = CA_UNAUTHORIZED_REQ;
+ responseInfo.info.dataType = CA_RESPONSE_DATA;
if (CA_STATUS_OK == CASendResponse(context->amsMgrContext->endpoint, &responseInfo))
{
*/
void SRMRequestHandler(const CAEndpoint_t *endPoint, const CARequestInfo_t *requestInfo)
{
- OIC_LOG(DEBUG, TAG, "Received request from remote device");
+ OIC_LOG_V(DEBUG, TAG, "%s:Received request from remote device", __func__);
+ bool isRequestOverSecureChannel = false;
if (!endPoint || !requestInfo)
{
OIC_LOG(ERROR, TAG, "Invalid arguments");
// Copy the subjectID
OicUuid_t subjectId = {.id = {0}};
memcpy(subjectId.id, requestInfo->info.identity.id, sizeof(subjectId.id));
+ if (endPoint->flags & CA_SECURE)
+ {
+ OIC_LOG(INFO, TAG, "request over secure channel");
+ isRequestOverSecureChannel = true;
+ }
//Check the URI has the query and skip it before checking the permission
+ if (NULL == requestInfo->info.resourceUri)
+ {
+ OIC_LOG(ERROR, TAG, "Invalid resourceUri");
+ return;
+ }
+
char *uri = strstr(requestInfo->info.resourceUri, "?");
int position = 0;
if (uri)
SetResourceRequestType(&g_policyEngineContext, newUri);
+ // Form a 'Error', 'slow response' or 'access deny' response and send to peer
+ CAResponseInfo_t responseInfo = {.result = CA_EMPTY};
+ memcpy(&responseInfo.info, &(requestInfo->info), sizeof(responseInfo.info));
+ responseInfo.info.payload = NULL;
+ responseInfo.info.dataType = CA_RESPONSE_DATA;
+
+ OCResource *resPtr = FindResourceByUri(newUri);
+ if (NULL != resPtr)
+ {
+ // All vertical secure resources and SVR resources other than DOXM & PSTAT should reject request
+ // over coap.
+ if ((((resPtr->resourceProperties) & OC_SECURE)
+ && (g_policyEngineContext.resourceType == NOT_A_SVR_RESOURCE))
+ || ((g_policyEngineContext.resourceType < OIC_SEC_SVR_TYPE_COUNT)
+ && (g_policyEngineContext.resourceType != OIC_R_DOXM_TYPE)
+ && (g_policyEngineContext.resourceType != OIC_R_PSTAT_TYPE)))
+ {
+ // if resource is secure and request is over insecure channel
+ if (!isRequestOverSecureChannel)
+ {
+ // Reject all the requests over coap for secure resource.
+ responseInfo.result = CA_FORBIDDEN_REQ;
+ if (CA_STATUS_OK != CASendResponse(endPoint, &responseInfo))
+ {
+ OIC_LOG(ERROR, TAG, "Failed in sending response to a unauthorized request!");
+ }
+ return;
+ }
+ }
+ }
+#ifdef MULTIPLE_OWNER
+ /*
+ * In case of ACL and CRED, The payload required to verify the payload.
+ * Payload information will be used for subowner's permission verification.
+ */
+ g_policyEngineContext.payload = (uint8_t*)requestInfo->info.payload;
+ g_policyEngineContext.payloadSize = requestInfo->info.payloadSize;
+#endif //MULTIPLE_OWNER
+
//New request are only processed if the policy engine state is AWAITING_REQUEST.
if (AWAITING_REQUEST == g_policyEngineContext.state)
{
if (IsAccessGranted(response) && gRequestHandler)
{
- return (gRequestHandler(endPoint, requestInfo));
+ gRequestHandler(endPoint, requestInfo);
+ return;
}
- // Form a 'Error', 'slow response' or 'access deny' response and send to peer
- CAResponseInfo_t responseInfo = {.result = CA_EMPTY};
- memcpy(&responseInfo.info, &(requestInfo->info), sizeof(responseInfo.info));
- responseInfo.info.payload = NULL;
-
VERIFY_NON_NULL(TAG, gRequestHandler, ERROR);
if (ACCESS_WAITING_FOR_AMS == response)
*/
void SRMResponseHandler(const CAEndpoint_t *endPoint, const CAResponseInfo_t *responseInfo)
{
- OIC_LOG(DEBUG, TAG, "Received response from remote device");
+ OIC_LOG_V(DEBUG, TAG, "%s:Received response from remote device", __func__);
// isProvResponse flag is to check whether response is catered by provisioning APIs or not.
// When token sent by CA response matches with token generated by provisioning request,
*/
void SRMErrorHandler(const CAEndpoint_t *endPoint, const CAErrorInfo_t *errorInfo)
{
- OIC_LOG_V(INFO, TAG, "Received error from remote device with result, %d for request uri, %s",
- errorInfo->result, errorInfo->info.resourceUri);
+ OIC_LOG_V(INFO, TAG, "%s:Received error from remote device with result, %d for request uri, %s",
+ __func__, errorInfo->result, errorInfo->info.resourceUri);
if (gErrorHandler)
{
gErrorHandler(endPoint, errorInfo);
gErrorHandler = errHandler;
-#if defined(__WITH_DTLS__)
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
CARegisterHandler(SRMRequestHandler, SRMResponseHandler, SRMErrorHandler);
#else
CARegisterHandler(reqHandler, respHandler, errHandler);
OIC_LOG(ERROR, TAG, "The persistent storage handler is invalid");
return OC_STACK_INVALID_PARAM;
}
+
gPersistentStorageHandler = persistentStorageHandler;
- return OC_STACK_OK;
+
+ // Check validity of Persistent Storage
+ OCStackResult res = OC_STACK_SVR_DB_NOT_EXIST;
+ res = CheckPersistentStorage(persistentStorageHandler);
+ if (OC_STACK_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "Persistent storage is not normal");
+ gPersistentStorageHandler = NULL;
+ }
+ return res;
}
OCPersistentStorage* SRMGetPersistentStorageHandler()
// behavior (for when SVR DB is missing) is settled.
InitSecureResources();
OCStackResult ret = OC_STACK_OK;
-#if defined(__WITH_DTLS__)
- if(CA_STATUS_OK != CARegisterDTLSCredentialsHandler(GetDtlsPskCredentials))
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+ if (CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskCredentials))
{
- OIC_LOG(ERROR, TAG, "Failed to revert DTLS credential handler.");
+ OIC_LOG(ERROR, TAG, "Failed to revert TLS credential handler.");
ret = OC_STACK_ERROR;
}
-
-#endif // (__WITH_DTLS__)
-#if defined(__WITH_X509__)
- CARegisterDTLSX509CredentialsHandler(GetDtlsX509Credentials);
- CARegisterDTLSCrlHandler(GetDerCrl);
-#endif // (__WITH_X509__)
-
+ CAregisterPkixInfoHandler(GetPkixInfo);
+ CAregisterGetCredentialTypesHandler(InitCipherSuiteList);
+#endif // __WITH_DTLS__ or __WITH_TLS__
return ret;
}
void SRMDeInitPolicyEngine()
{
- return DeInitPolicyEngine(&g_policyEngineContext);
+ DeInitPolicyEngine(&g_policyEngineContext);
}
bool SRMIsSecurityResourceURI(const char* uri)
}
const char *rsrcs[] = {
- OIC_RSRC_SVC_URI,
OIC_RSRC_AMACL_URI,
OIC_RSRC_CRL_URI,
OIC_RSRC_CRED_URI,
OIC_RSRC_PCONF_URI,
OIC_RSRC_DPAIRING_URI,
OIC_RSRC_VER_URI,
+ OC_RSRVD_PROV_CRL_URL
};
// Remove query from Uri for resource string comparison
}
/**
+ * Check whether persistent storage is valid
+ * @return OC_STACK_OK if valid, other errors otherwise;
+ */
+OCStackResult CheckPersistentStorage(OCPersistentStorage* ps)
+{
+ OIC_LOG_V(INFO, TAG, "In %s", __func__);
+
+ FILE *fp = NULL;
+ OCStackResult ret = OC_STACK_SVR_DB_NOT_EXIST;
+ OicSecDoxm_t* doxm = NULL;
+ OicSecPstat_t* pstat = NULL;
+ uint8_t *data = NULL;
+ size_t size = 0;
+
+ if (NULL == ps)
+ {
+ OIC_LOG(ERROR, TAG, "NULL PersistentStorage Parameter");
+ ret = OC_STACK_INVALID_PARAM;
+ goto exit;
+ }
+
+ // Check whether the DB file exists
+ fp = ps->open(SVR_DB_DAT_FILE_NAME, "r+b");
+ if (NULL == fp)
+ {
+ OIC_LOG(ERROR, TAG, "DB file cannot be opened");
+ ret = OC_STACK_SVR_DB_NOT_EXIST;
+ SetPSStatus(PS_OPEN_FAIL);
+ goto exit;
+ }
+ ps->close(fp);
+
+ OIC_LOG(INFO, TAG, "Checking doxm resource...");
+ //Check DOXM resource
+ ret = GetSecureVirtualDatabaseFromPS2(ps, OIC_JSON_DOXM_NAME, &data, &size);
+ // If database read failed
+ if (OC_STACK_OK != ret)
+ {
+ OIC_LOG (ERROR, TAG, "Can not find the DOXM Resource in SVR DB.");
+ ret = OC_STACK_INCONSISTENT_DB;
+ SetPSStatus(PS_PARSE_FAIL);
+ goto exit;
+ }
+ if (data && 0 < size)
+ {
+ // Read DOXM resource from PS
+ ret = CBORPayloadToDoxm(data, size, &doxm);
+ if (OC_STACK_OK != ret)
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed to Convert CBOR to Doxm bin : %d", ret);
+ ret = OC_STACK_INCONSISTENT_DB;
+ SetPSStatus(PS_PARSE_FAIL);
+ goto exit;
+ }
+ }
+ else
+ {
+ ret = OC_STACK_INCONSISTENT_DB;
+ SetPSStatus(PS_PARSE_FAIL);
+ goto exit;
+ }
+ if (data)
+ {
+ OICFree(data);
+ data = NULL;
+ }
+
+ OIC_LOG(INFO, TAG, "Checking pstat resource...");
+ //Check PSTAT resource
+ ret = GetSecureVirtualDatabaseFromPS2(ps, OIC_JSON_PSTAT_NAME, &data, &size);
+ // If database read failed
+ if (OC_STACK_OK != ret)
+ {
+ OIC_LOG (ERROR, TAG, "Can not find the PSTAT Resource in SVR DB.");
+ ret = OC_STACK_INCONSISTENT_DB;
+ SetPSStatus(PS_PARSE_FAIL);
+ goto exit;
+ }
+ if (data && 0 < size)
+ {
+ // Read ACL resource from PS
+ ret = CBORPayloadToPstat(data, size, &pstat);
+ if (OC_STACK_OK != ret)
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed to Convert CBOR to PSTAT bin : %d", ret);
+ ret = OC_STACK_INCONSISTENT_DB;
+ SetPSStatus(PS_PARSE_FAIL);
+ goto exit;
+ }
+ }
+ else
+ {
+ ret = OC_STACK_INCONSISTENT_DB;
+ SetPSStatus(PS_PARSE_FAIL);
+ goto exit;
+ }
+ if (data)
+ {
+ OICFree(data);
+ data = NULL;
+ }
+
+ SetPSStatus(PS_NORMAL);
+
+ ret = OC_STACK_OK;
+ OIC_LOG(INFO, TAG, "All Secure Virtual Resources are fine.");
+
+exit:
+ if (data)
+ {
+ OICFree(data);
+ }
+ if (doxm)
+ {
+ DeleteDoxmBinData(doxm);
+ }
+ if (pstat)
+ {
+ DeletePstatBinData(pstat);
+ }
+
+ OIC_LOG_V(INFO, TAG, "Out %s", __func__);
+
+ return ret;
+}
+
+/**
* Get the Secure Virtual Resource (SVR) type from the URI.
* @param uri [IN] Pointer to URI in question.
* @return The OicSecSvrType_t of the URI passed (note: if not a Secure Virtual
}
}
- svrLen = strlen(OIC_RSRC_SVC_URI);
- if(uriLen == svrLen)
- {
- if(0 == strncmp(uri, OIC_RSRC_SVC_URI, svrLen))
- {
- return OIC_R_SVC_TYPE;
- }
- }
-
svrLen = strlen(OIC_RSRC_SACL_URI);
if(uriLen == svrLen)
{