Merge branch 'master' into iot-1785
authorKevin Kane <kkane@microsoft.com>
Wed, 22 Mar 2017 02:26:26 +0000 (19:26 -0700)
committerKevin Kane <kkane@microsoft.com>
Wed, 22 Mar 2017 02:26:30 +0000 (19:26 -0700)
Change-Id: If30ba205d4fcb0b5dc969f83d464509a8059ef3f
Signed-off-by: Kevin Kane <kkane@microsoft.com>
1  2 
resource/csdk/connectivity/api/cacommon.h
resource/csdk/security/SConscript
resource/csdk/security/include/securevirtualresourcetypes.h
resource/csdk/security/src/secureresourcemanager.c

index 867beee,340a8a0..867beee
mode 100755,100644..100644
@@@ -128,18 -128,6 +128,18 @@@ extern "C
  #define CA_OPTION_URI_QUERY 15
  #define CA_OPTION_ACCEPT 17
  #define CA_OPTION_LOCATION_QUERY 20
 +        
 +/**
 + * @def UUID_PREFIX
 + * @brief uuid prefix in certificate subject field
 + */
 +#define UUID_PREFIX "uuid:"
 +
 +/**
 + * @def SUBJECT_PREFIX
 + * @brief prefix for specifying part of a cert's subject for a particular uuid
 + */
 +#define SUBJECT_PREFIX "CN=" UUID_PREFIX
  
  /**
  * TODO: Move these COAP defines to CoAP lib once approved.
@@@ -328,8 -316,6 +328,8 @@@ typedef struc
  #endif
  } CAEndpoint_t;
  
 +#define CA_SECURE_ENDPOINT_PUBLIC_KEY_MAX_LENGTH    (128)
 +
  /**
   * Endpoint information for secure messages.
   */
@@@ -340,8 -326,6 +340,8 @@@ typedef struc
      CARemoteId_t identity;      /**< endpoint device uuid */
      CARemoteId_t userId;        /**< endpoint user uuid */
      uint32_t attributes;
 +    uint8_t publicKey[CA_SECURE_ENDPOINT_PUBLIC_KEY_MAX_LENGTH]; /**< Peer's DER-encoded public key (if using certificate) */
 +    size_t publicKeyLength;     /**< Length of publicKey; zero if not using certificate */
  } CASecureEndpoint_t;
  
  /**
@@@ -59,13 -59,7 +59,10 @@@ libocsrm_env.PrependUnique(CPPPATH = 
  
  if target_os in ['windows', 'msys_nt']:
        libocsrm_env.AppendUnique(LIBPATH = [os.path.join(libocsrm_env.get('BUILD_DIR'), 'resource', 'oc_logger')])
-     # Enable W4 but disable the following warning:
-     #  - warning C4232: nonstandard extension used: 'read': address of dllimport 'fread' is not static, identity not guaranteed
-     #    - fread, frwrite, etc are provided by the platform and cannot be changed.
 -      libocsrm_env.AppendUnique(CCFLAGS=['/W4', '/WX'])
 +    #  - warning C4200: nonstandard extension used: zero-sized array in struct/union
 +    #  - warning C4214: nonstandard extension used: bit field types other than int
 +    #    - warnings inherited from a header included from libcoap
-       libocsrm_env.AppendUnique(CCFLAGS=['/wd4232', '/wd4200', '/wd4214', '/W4', '/WX'])
++      libocsrm_env.AppendUnique(CCFLAGS=['/wd4200', '/wd4214', '/W4', '/WX'])
  
  if target_os in ['linux', 'android', 'tizen', 'msys_nt', 'windows'] and libocsrm_env.get('SECURED') == '1':
        SConscript('provisioning/SConscript', 'libocsrm_env')
@@@ -129,9 -123,6 +126,9 @@@ if libocsrm_env.get('SECURED') == '1'
        libocsrm_src = libocsrm_src + [OCSRM_SRC + 'oxmpincommon.c', OCSRM_SRC + 'pbkdf2.c']
        libocsrm_src = libocsrm_src + [OCSRM_SRC + 'crlresource.c', OCSRM_SRC + 'pkix_interface.c']
        libocsrm_src = libocsrm_src + [OCSRM_SRC + 'oxmverifycommon.c']
 +      libocsrm_src = libocsrm_src + [OCSRM_SRC + 'certhelpers.c', OCSRM_SRC + 'occertutility.c']
 +      libocsrm_src = libocsrm_src + [OCSRM_SRC + 'csrresource.c']
 +      libocsrm_src = libocsrm_src + [OCSRM_SRC + 'rolesresource.c']
  
  if target_os in ['windows', 'msys_nt']:
        libocsrm_src  = libocsrm_src + [OCSRM_SRC + 'strptime.c']
   * will have to be written by hand to marshal these structures (e.g. to/from
   * Persistent Storage, or across memory boundaries).
   *
+  * We're using uint typedefs for all enum types to avoid C++ type conversion
+  * errors and enable bitfield operations on these fields (causes compilation
+  * errors on arduino builds). This may miss some type checks, but it's
+  * nearly impossible to do int/bitfield operations on enum types in C++.
+  *
   * TODO reconcile against latest OIC Security Spec to ensure all fields correct.
   * (Last checked against v0.95)
   */
@@@ -108,7 -113,7 +113,7 @@@ extern "C" 
   *     }
   * }
   */
typedef enum
+ enum
  {
      ACCESS_GRANTED = ACCESS_GRANTED_DEF,
      ACCESS_DENIED = ACCESS_DENIED_DEF,
          | POLICY_ENGINE_ERROR_DEF,
      ACCESS_DENIED_SEC_RESOURCE_OVER_UNSECURE_CHANNEL = ACCESS_DENIED_DEF
          | SEC_RESOURCE_OVER_UNSECURE_CHANNEL_DEF,
- } SRMAccessResponse_t;
+ };
+ typedef unsigned int SRMAccessResponse_t;
  
  /**
   * Reason code for SRMAccessResponse.
   */
typedef enum
+ enum
  {
      NO_REASON_GIVEN = 0,
      INSUFFICIENT_PERMISSION = INSUFFICIENT_PERMISSION_DEF,
      SUBJECT_NOT_FOUND = SUBJECT_NOT_FOUND_DEF,
      RESOURCE_NOT_FOUND = RESOURCE_NOT_FOUND_DEF,
- } SRMAccessResponseReasonCode_t;
+ };
+ typedef unsigned int SRMAccessResponseReasonCode_t;
  
  /**
   * Extract Reason Code from Access Response.
@@@ -184,7 -193,7 +193,7 @@@ typedef struct OicSecCred OicSecCred_t
   *      // ct contains PIN_PASSWORD flag.
   *  }
   */
typedef enum OSCTBitmask
+ enum OSCTBitmask
  {
      NO_SECURITY_MODE                = 0x0,
      SYMMETRIC_PAIR_WISE_KEY         = (0x1 << 0),
      SIGNED_ASYMMETRIC_KEY           = (0x1 << 3),
      PIN_PASSWORD                    = (0x1 << 4),
      ASYMMETRIC_ENCRYPTION_KEY       = (0x1 << 5),
- } OSCTBitmask_t;
+ };
+ typedef unsigned int OSCTBitmask_t;
  
  /**
   * /oic/sec/credtype (Credential Type) data type.
@@@ -209,7 -220,10 +220,10 @@@ typedef OSCTBitmask_t OicSecCredType_t
  
  typedef struct OicSecDoxm OicSecDoxm_t;
  
- typedef enum OicSecDpm
+ /**
+  * The oic.sec.dpmtype
+  */
+ enum OicSecDpm
  {
      NORMAL                          = 0x0,
      RESET                           = (0x1 << 0),
      SECURITY_MANAGEMENT_SERVICES    = (0x1 << 3),
      PROVISION_CREDENTIALS           = (0x1 << 4),
      PROVISION_ACLS                  = (0x1 << 5),
+     VERIFY_SOFTWARE_VERSION         = (0x1 << 6),
+     UPDATE_SOFTWARE                 = (0x1 << 7),
  #ifdef MULTIPLE_OWNER
-     TAKE_SUB_OWNER                  = (0x1 << 6),
+     TAKE_SUB_OWNER                  = (0x1 << 13),
  #endif
-     // << 7 THROUGH 15 RESERVED
- } OicSecDpm_t;
+ };
+ typedef unsigned int OicSecDpm_t;
  
  // These types are taken from the Security Spec v1.1.12 /pstat resource definition
  // Note that per the latest spec, there is NO definition for Multiple Service Client Directed
  // provisioning mode, so that enum value has been removed.
typedef enum OicSecDpom
+ enum OicSecDpom
  {
      MULTIPLE_SERVICE_SERVER_DRIVEN    = (0x1 << 0),
      SINGLE_SERVICE_SERVER_DRIVEN      = (0x1 << 1),
      SINGLE_SERVICE_CLIENT_DRIVEN      = (0x1 << 2),
- } OicSecDpom_t;
+ };
  
- typedef enum OicSecSvcType
+ typedef unsigned int OicSecDpom_t;
+ enum OicSecSvcType
  {
      SERVICE_UNKNOWN                 = 0x0,
      ACCESS_MGMT_SERVICE             = 0x1,  //urn:oic.sec.ams
- } OicSecSvcType_t;
+ };
  
+ typedef unsigned int OicSecSvcType_t;
  
  //TODO: Need more clarification on deviceIDFormat field type.
  #if 0
typedef enum
+ enum
  {
      URN = 0x0
- }OicSecDvcIdFrmt_t;
+ };
+ typedef unsigned int OicSecDvcIdFrmt_t;
  #endif
  
typedef enum
+ enum
  {
      OIC_RESOURCE_TYPE_ERROR = 0,
      OIC_R_ACL_TYPE,
      OIC_R_AMACL_TYPE,
      OIC_R_CRED_TYPE,
      OIC_R_CRL_TYPE,
 +    OIC_R_CSR_TYPE,
      OIC_R_DOXM_TYPE,
      OIC_R_DPAIRING_TYPE,
      OIC_R_PCONF_TYPE,
      OIC_R_PSTAT_TYPE,
 +    OIC_R_ROLES_TYPE,
      OIC_R_SACL_TYPE,
      OIC_R_SVC_TYPE,
      OIC_SEC_SVR_TYPE_COUNT, //define the value to number of SVR
      NOT_A_SVR_RESOURCE = 99
- }OicSecSvrType_t;
+ };
  
- typedef enum
+ typedef unsigned int OicSecSvrType_t;
+ enum
  {
      OIC_JUST_WORKS                          = 0x0,
      OIC_RANDOM_DEVICE_PIN                   = 0x1,
  #endif //MULTIPLE_OWNER
      OIC_MV_JUST_WORKS                       = 0xFF01,
      OIC_CON_MFG_CERT                        = 0xFF02,
- }OicSecOxm_t;
+ };
  
- typedef enum
+ typedef unsigned int OicSecOxm_t;
+ enum
  {
      OIC_ENCODING_UNKNOW = 0,
      OIC_ENCODING_RAW = 1,
      OIC_ENCODING_BASE64 = 2,
      OIC_ENCODING_PEM = 3,
      OIC_ENCODING_DER = 4
- }OicEncodingType_t;
+ };
+ typedef unsigned int OicEncodingType_t;
  
  #ifdef MULTIPLE_OWNER
typedef enum
+ enum
  {
      MOT_STATUS_READY = 0,
      MOT_STATUS_IN_PROGRESS = 1,
      MOT_STATUS_DONE = 2,
- }MotStatus_t;
+ };
+ typedef unsigned int MotStatus_t;
  #endif //MULTIPLE_OWNER
  
  /**
   * 1 : Enable multiple owner (Always on)
   * 2 : Timely multiple owner enable
   */
typedef enum
+ enum
  {
      OIC_MULTIPLE_OWNER_DISABLE = 0,
      OIC_MULTIPLE_OWNER_ENABLE = 1,
      OIC_MULTIPLE_OWNER_TIMELY_ENABLE = 2,
      OIC_NUMBER_OF_MOM_TYPE = 3
- }OicSecMomType_t;
+ };
+ typedef unsigned int OicSecMomType_t;
  
  typedef struct OicSecKey OicSecKey_t;
  
@@@ -349,8 -379,7 +381,8 @@@ typedef void OicSecCert_t
   */
  #define UUID_LENGTH 128/8 // 128-bit GUID length
  //TODO: Confirm the length and type of ROLEID.
 -#define ROLEID_LENGTH 128/8 // 128-bit ROLEID length
 +#define ROLEID_LENGTH 64 // 64-byte authority max length
 +#define ROLEAUTHORITY_LENGTH 64 // 64-byte authority max length
  #define OWNER_PSK_LENGTH_128 128/8 //byte size of 128-bit key size
  #define OWNER_PSK_LENGTH_256 256/8 //byte size of 256-bit key size
  
@@@ -404,41 -433,10 +436,41 @@@ struct OicSecValidit
      OicSecValidity_t *next;
  };
  
 +typedef enum
 +{
 +    OIC_SEC_ACL_UNKNOWN = 0,
 +    OIC_SEC_ACL_V1 = 1,
 +    OIC_SEC_ACL_V2 = 2
 +} OicSecAclVersion_t;
 +
 +#define OIC_SEC_ACL_LATEST OIC_SEC_ACL_V2
 +
 +typedef enum
 +{
 +    OicSecAceUuidSubject = 0, /* Default to this type. */
 +    OicSecAceRoleSubject
 +} OicSecAceSubjectType;
 +
 +/**
 + * /oic/sec/role (Role) data type.
 + * Derived from OIC Security Spec; see Spec for details.
 + */
 +struct OicSecRole
 +{
 +    // <Attribute ID>:<Read/Write>:<Multiple/Single>:<Mandatory?>:<Type>
 +    char id[ROLEID_LENGTH];                 // 0:R:S:Y:String
 +    char authority[ROLEAUTHORITY_LENGTH];   // 1:R:S:N:String
 +};
 +
  struct OicSecAce
  {
      // <Attribute ID>:<Read/Write>:<Multiple/Single>:<Mandatory?>:<Type>
 -    OicUuid_t subjectuuid;              // 0:R:S:Y:uuid
 +    OicSecAceSubjectType subjectType;
 +    union                               // 0:R:S:Y:{roletype|didtype|"*"}
 +    {
 +        OicUuid_t subjectuuid;          // Only valid for subjectType == OicSecAceUuidSubject
 +        OicSecRole_t subjectRole;       // Only valid for subjectType == OicSecAceRoleSubject
 +    };
      OicSecRsrc_t *resources;            // 1:R:M:Y:Resource
      uint16_t permission;                // 2:R:S:Y:UINT16
      OicSecValidity_t *validities;       // 3:R:M:N:Time-interval
@@@ -544,8 -542,8 +576,8 @@@ struct OicSecPsta
  {
      // <Attribute ID>:<Read/Write>:<Multiple/Single>:<Mandatory?>:<Type>
      bool                isOp;           // 0:R:S:Y:Boolean
-     OicSecDpm_t         cm;             // 1:R:S:Y:oic.sec.dpm
-     OicSecDpm_t         tm;             // 2:RW:S:Y:oic.sec.dpm
+     OicSecDpm_t         cm;             // 1:R:S:Y:oic.sec.dpmtype
+     OicSecDpm_t         tm;             // 2:RW:S:Y:oic.sec.dpmtype
      OicSecDpom_t        om;             // 4:RW:M:Y:oic.sec.dpom
      size_t              smLen;          // the number of elts in Sm
      OicSecDpom_t        *sm;            // 5:R:M:Y:oic.sec.dpom
  };
  
  /**
 - * /oic/sec/role (Role) data type.
 - * Derived from OIC Security Spec; see Spec for details.
 - */
 -struct OicSecRole
 -{
 -    // <Attribute ID>:<Read/Write>:<Multiple/Single>:<Mandatory?>:<Type>
 -    //TODO fill in with Role definition
 -    uint8_t             id[ROLEID_LENGTH];
 -};
 -
 -/**
   * /oic/sec/sacl (Signed Access Control List) data type.
   * Derived from OIC Security Spec; see Spec for details.
   */
@@@ -594,14 -603,14 +626,14 @@@ typedef struct OicSecDpairing OicSecDpa
   *              1:  pre-configured pin
   *              2:  random pin
   */
typedef enum PRMBitmask
+ enum PRMBitmask
  {
      PRM_NOT_ALLOWED             = 0x0,
      PRM_PRE_CONFIGURED        = (0x1 << 0),
      PRM_RANDOM_PIN               = (0x1 << 1),
- } PRMBitmask_t;
+ };
  
- typedef PRMBitmask_t OicSecPrm_t;
+ typedef unsigned int OicSecPrm_t;
  
  
  struct OicPin
@@@ -32,6 -32,7 +32,7 @@@
  #include "secureresourcemanager.h"
  #include "srmresourcestrings.h"
  #include "ocresourcehandler.h"
+ #include "ocrandom.h"
  
  #if defined( __WITH_TLS__) || defined(__WITH_DTLS__)
  #include "pkix_interface.h"
@@@ -105,7 -106,7 +106,7 @@@ void SRMGenerateResponse(SRMRequestCont
      // on to resource endpoint.
      if (IsAccessGranted(context->responseVal))
      {
-         if(NULL != gRequestHandler
+         if (NULL != gRequestHandler
              && NULL != context->endPoint
              && NULL != context->requestInfo)
          {
@@@ -174,7 -175,7 +175,7 @@@ void CheckRequestForSecResourceOverUnse
          context->resourceType, context->resourceUri);
  
      // if request is over unsecure channel, check resource type
-     if(false == context->secureChannel)
+     if (false == context->secureChannel)
      {
          OCResource *resPtr = FindResourceByUri(context->resourceUri);
  
@@@ -240,22 -241,34 +241,34 @@@ void ClearRequestContext(SRMRequestCont
  }
  
  // Returns true iff Request arrived over secure channel
+ // Note: context->subjectUuid must be copied from requestInfo prior to calling
+ // this function, or this function may incorrectly read the nil-UUID (0s)
+ // and assume CoAP request (which can result in request being incorrectly
+ // denied).
  bool isRequestOverSecureChannel(SRMRequestContext_t *context)
  {
      OicUuid_t nullSubjectId = {.id = {0}};
  
-     // if flag set, return true
-     if(context->endPoint->flags & CA_SECURE)
+     // If flag set, return true
+     if (context->endPoint->flags & CA_SECURE)
      {
+         OIC_LOG(DEBUG, TAG, "CA_SECURE flag is set; indicates secure channel.");
          return true;
      }
-     // a null subject ID indicates CoAP, so if non-null, also return true
-     else if(memcmp(context->requestInfo->info.identity.id,
-         nullSubjectId.id, sizeof(context->requestInfo->info.identity.id)) != 0)
+     // A null subject ID indicates CoAP, so if non-null, also return true
+     if (SUBJECT_ID_TYPE_UUID == context->subjectIdType)
      {
-         return true;
+         if (memcmp(context->subjectUuid.id, nullSubjectId.id,
+             sizeof(context->subjectUuid.id)) != 0)
+         {
+             OIC_LOG(DEBUG, TAG, "Subject ID is non-null; indicates secure channel.");
+             return true;
+         }
      }
  
+     OIC_LOG(DEBUG, TAG, "CA_SECURE flag is not set, and Subject ID of requester \
+         is NULL; indicates unsecure channel.");
      return false;
  }
  
@@@ -284,10 -297,26 +297,26 @@@ void SRMRequestHandler(const CAEndpoint
          ctx->requestInfo = requestInfo;
          ctx->requestedPermission = GetPermissionFromCAMethod_t(requestInfo->method);
  
-         // Copy the subjectID.
+         // Copy the subjectID, truncating to 16-byte UUID (32 hex-digits).
+         // TODO IOT-1894 "Determine appropriate CA_MAX_ENDPOINT_IDENTITY_LEN"
+         ctx->subjectIdType = SUBJECT_ID_TYPE_UUID; // only supported type for now
          memcpy(ctx->subjectUuid.id,
              requestInfo->info.identity.id, sizeof(ctx->subjectUuid.id));
-         ctx->subjectIdType = SUBJECT_ID_TYPE_UUID; // only supported type for now
+ #ifndef NDEBUG // if debug build, log the ID being used for matching ACEs
+         if (SUBJECT_ID_TYPE_UUID == ctx->subjectIdType)
+         {
+             char strUuid[UUID_STRING_SIZE] = "UUID_ERROR";
+             if (OCConvertUuidToString(ctx->subjectUuid.id, strUuid))
+             {
+                 OIC_LOG_V(DEBUG, TAG, "ctx->subjectUuid for request: %s.", strUuid);
+             }
+             else
+             {
+                 OIC_LOG(ERROR, TAG, "failed to convert ctx->subjectUuid to str.");
+             }
+         }
+ #endif
  
          // Set secure channel boolean.
          ctx->secureChannel = isRequestOverSecureChannel(ctx);
          CheckRequestForSecResourceOverUnsecureChannel(ctx);
  
          // If DENIED response wasn't sent already, then it's time to check ACL.
-         if(false == ctx->responseSent)
+         if (false == ctx->responseSent)
          {
  #ifdef MULTIPLE_OWNER // TODO Samsung: please verify that these two calls belong
                        // here inside this conditional statement.
          }
      }
  
-     if(false == ctx->responseSent)
+     if (false == ctx->responseSent)
      {
          OIC_LOG(ERROR, TAG, "Exiting SRM without responding to requester!");
      }
@@@ -383,7 -412,7 +412,7 @@@ OCStackResult SRMRegisterHandler(CARequ
      CAResponseCallback respHandler, CAErrorCallback errHandler)
  {
      OIC_LOG(DEBUG, TAG, "SRMRegisterHandler !!");
-     if!reqHandler || !respHandler || !errHandler)
+     if (!reqHandler || !respHandler || !errHandler)
      {
          OIC_LOG(ERROR, TAG, "Callback handlers are invalid");
          return OC_STACK_INVALID_PARAM;
@@@ -452,14 -481,12 +481,14 @@@ bool SRMIsSecurityResourceURI(const cha
          OIC_RSRC_AMACL_URI,
          OIC_RSRC_CRL_URI,
          OIC_RSRC_CRED_URI,
 +        OIC_RSRC_CSR_URI,
          OIC_RSRC_ACL_URI,
          OIC_RSRC_DOXM_URI,
          OIC_RSRC_PSTAT_URI,
          OIC_RSRC_PCONF_URI,
          OIC_RSRC_DPAIRING_URI,
          OIC_RSRC_VER_URI,
 +        OIC_RSRC_ROLES_URI,
          OC_RSRVD_PROV_CRL_URL
      };
  
@@@ -514,108 -541,90 +543,108 @@@ OicSecSvrType_t GetSvrTypeFromUri(cons
      size_t svrLen = 0;
  
      svrLen = strlen(OIC_RSRC_ACL_URI);
-     if(uriLen == svrLen)
+     if (uriLen == svrLen)
      {
-         if(0 == strncmp(uri, OIC_RSRC_ACL_URI, svrLen))
+         if (0 == strncmp(uri, OIC_RSRC_ACL_URI, svrLen))
          {
              return OIC_R_ACL_TYPE;
          }
      }
  
      svrLen = strlen(OIC_RSRC_AMACL_URI);
-     if(uriLen == svrLen)
+     if (uriLen == svrLen)
      {
-         if(0 == strncmp(uri, OIC_RSRC_AMACL_URI, svrLen))
+         if (0 == strncmp(uri, OIC_RSRC_AMACL_URI, svrLen))
          {
              return OIC_R_AMACL_TYPE;
          }
      }
  
      svrLen = strlen(OIC_RSRC_CRED_URI);
-     if(uriLen == svrLen)
+     if (uriLen == svrLen)
      {
-         if(0 == strncmp(uri, OIC_RSRC_CRED_URI, svrLen))
+         if (0 == strncmp(uri, OIC_RSRC_CRED_URI, svrLen))
          {
              return OIC_R_CRED_TYPE;
          }
      }
  
      svrLen = strlen(OIC_RSRC_CRL_URI);
-     if(uriLen == svrLen)
+     if (uriLen == svrLen)
      {
-         if(0 == strncmp(uri, OIC_RSRC_CRL_URI, svrLen))
+         if (0 == strncmp(uri, OIC_RSRC_CRL_URI, svrLen))
          {
              return OIC_R_CRL_TYPE;
          }
      }
  
 +    svrLen = strlen(OIC_RSRC_CSR_URI);
 +    if (uriLen == svrLen)
 +    {
 +        if (0 == strncmp(uri, OIC_RSRC_CSR_URI, svrLen))
 +        {
 +            return OIC_R_CSR_TYPE;
 +        }
 +    }
 +
      svrLen = strlen(OIC_RSRC_DOXM_URI);
-     if(uriLen == svrLen)
+     if (uriLen == svrLen)
      {
-         if(0 == strncmp(uri, OIC_RSRC_DOXM_URI, svrLen))
+         if (0 == strncmp(uri, OIC_RSRC_DOXM_URI, svrLen))
          {
              return OIC_R_DOXM_TYPE;
          }
      }
  
      svrLen = strlen(OIC_RSRC_DPAIRING_URI);
-     if(uriLen == svrLen)
+     if (uriLen == svrLen)
      {
-         if(0 == strncmp(uri, OIC_RSRC_DPAIRING_URI, svrLen))
+         if (0 == strncmp(uri, OIC_RSRC_DPAIRING_URI, svrLen))
          {
              return OIC_R_DPAIRING_TYPE;
          }
      }
  
      svrLen = strlen(OIC_RSRC_PCONF_URI);
-     if(uriLen == svrLen)
+     if (uriLen == svrLen)
      {
-         if(0 == strncmp(uri, OIC_RSRC_PCONF_URI, svrLen))
+         if (0 == strncmp(uri, OIC_RSRC_PCONF_URI, svrLen))
          {
              return OIC_R_PCONF_TYPE;
          }
      }
  
      svrLen = strlen(OIC_RSRC_PSTAT_URI);
-     if(uriLen == svrLen)
+     if (uriLen == svrLen)
      {
-         if(0 == strncmp(uri, OIC_RSRC_PSTAT_URI, svrLen))
+         if (0 == strncmp(uri, OIC_RSRC_PSTAT_URI, svrLen))
          {
              return OIC_R_PSTAT_TYPE;
          }
      }
  
 +    svrLen = strlen(OIC_RSRC_ROLES_URI);
 +    if (uriLen == svrLen)
 +    {
 +        if (0 == strncmp(uri, OIC_RSRC_ROLES_URI, svrLen))
 +        {
 +            return OIC_R_ROLES_TYPE;
 +        }
 +    }
 +
      svrLen = strlen(OIC_RSRC_SVC_URI);
-     if(uriLen == svrLen)
+     if (uriLen == svrLen)
      {
-         if(0 == strncmp(uri, OIC_RSRC_SVC_URI, svrLen))
+         if (0 == strncmp(uri, OIC_RSRC_SVC_URI, svrLen))
          {
              return OIC_R_SVC_TYPE;
          }
      }
  
      svrLen = strlen(OIC_RSRC_SACL_URI);
-     if(uriLen == svrLen)
+     if (uriLen == svrLen)
      {
-         if(0 == strncmp(uri, OIC_RSRC_SACL_URI, svrLen))
+         if (0 == strncmp(uri, OIC_RSRC_SACL_URI, svrLen))
          {
              return OIC_R_SACL_TYPE;
          }