[IOT-2359][IOT-2360][IOT-2364] Separate provisioning with DOS
[platform/upstream/iotivity.git] / resource / csdk / security / provisioning / src / secureresourceprovider.c
index e75ea21..f191914 100644 (file)
@@ -17,6 +17,7 @@
  * limitations under the License.
  *
  * *****************************************************************/
+#include "iotivity_config.h"
 #include <stdio.h>
 #include <string.h>
 #include <stdint.h>
 #include "secureresourceprovider.h"
 #include "logger.h"
 #include "oic_malloc.h"
+#include "oic_string.h"
 #include "aclresource.h"
 #include "pstatresource.h"
 #include "srmresourcestrings.h"
 #include "credresource.h"
+#include "csrresource.h"
+#include "rolesresource.h"
 #include "doxmresource.h"
 #include "pconfresource.h"
 #include "credentialgenerator.h"
 #include "cainterface.h"
-#include "cJSON.h"
+#include "oic_string.h"
 #include "pmtypes.h"
 #include "pmutility.h"
+#include "srmutility.h"
 #include "provisioningdatabasemanager.h"
 #include "base64.h"
 #include "utlist.h"
 #include "ocpayload.h"
+#include "srmutility.h"
+#include "certhelpers.h"
 
-#ifdef __WITH_X509__
+#ifdef __WITH_DTLS__
 #include "crlresource.h"
-#endif // WITH_X509__
+#endif
 
-#define TAG "SRPAPI"
+#define TAG "OIC_SRPAPI"
 
-/**
- * Macro to verify argument is not equal to NULL.
- * eg: VERIFY_NON_NULL(TAG, ptrData, ERROR,OC_STACK_ERROR);
- */
-#define VERIFY_NON_NULL(tag, arg, logLevel, retValue) { if (NULL == (arg)) \
-            { OIC_LOG((logLevel), tag, #arg " is NULL"); return retValue; } }
+trustCertChainContext_t g_trustCertChainNotifier;
+
+// Enum type index for data types.
+typedef enum
+{
+    CHAIN_TYPE = 0,                       /**< Certificate trust chain.**/
+    ACL_TYPE,                             /**< Access control list.**/
+    PSK_TYPE,                             /**< Pre-Shared Key.**/
+    CERT_TYPE                             /**< X.509 certificate.**/
+} DataType_t;
 
 /**
- * Macro to verify success of operation.
- * eg: VERIFY_SUCCESS(TAG, OC_STACK_OK == foo(), ERROR, OC_STACK_ERROR);
+ * Structure to carry general data to callback.
  */
-#define VERIFY_SUCCESS(tag, op, logLevel, retValue) { if (!(op)) \
-            {OIC_LOG((logLevel), tag, #op " failed!!"); return retValue;} }
+typedef struct Data
+{
+    void *ctx;                                   /**< Pointer to user context.**/
+    DataType_t type;                             /**< Data type of the context.**/
+} Data_t;
 
 /**
  * Structure to carry credential data to callback.
  */
-typedef struct CredentialData CredentialData_t;
-struct CredentialData
+typedef struct CredentialData
 {
     void *ctx;                                  /**< Pointer to user context.**/
-    const OCProvisionDev_t *deviceInfo1;        /**< Pointer to OCProvisionDev_t.**/
-    const OCProvisionDev_t *deviceInfo2;        /**< Pointer to OCProvisionDev_t.**/
-    OicSecCred_t *credInfo;                     /**< Pointer to OicSecCred_t.**/
-    OicSecCred_t *credInfoFirst;                /**< Pointer to OicSecCred_t.**/
+    const OCProvisionDev_t *deviceInfo[2];      /**< Array of pointers to OCProvisionDev_t.**/
+    OicSecCred_t *credInfo[2];                  /**< Array of pointers to OicSecCred_t.**/
+    int currIndex;                              /**< Index of current remote device.**/
     OCProvisionResultCB resultCallback;         /**< Pointer to result callback.**/
     OCProvisionResult_t *resArr;                /**< Result array.**/
     int numOfResults;                           /**< Number of results in result array.**/
-};
+    OicSecCredType_t type;                      /**< Type of credentials to be provisioned to the device.**/
+    size_t keySize;                             /**< Size of key.**/
+    const char *pemCert;                        /**< Certificate (SIGNED_ASYMMETRIC_KEY) encoded as PEM.**/
+    const OicSecRole_t *role1;                  /**< Role of the deviceInfo[0].**/
+    const OicSecRole_t *role2;                  /**< Role of the deviceInfo[1].**/
+} CredentialData_t;
 
 /**
  * Structure to carry ACL provision API data to callback.
  */
-typedef struct ACLData ACLData_t;
-struct ACLData
+typedef struct ACLData
+{
+    void *ctx;                                   /**< Pointer to user context.**/
+    const OCProvisionDev_t *deviceInfo;          /**< Pointer to PMDevInfo_t.**/
+    OCProvisionResultCB resultCallback;         /**< Pointer to result callback.**/
+    OCProvisionResult_t *resArr;                 /**< Result array.**/
+    int numOfResults;                           /**< Number of results in result array.**/
+    OicSecAcl_t *acl;
+    OicSecAclVersion_t aclVersion;
+} ACLData_t;
+
+/**
+ * Structure to carry Trust Chain provision API data to callback.
+ */
+typedef struct TrustChainData
 {
     void *ctx;                                  /**< Pointer to user context.**/
-    const OCProvisionDev_t *deviceInfo;         /**< Pointer to PMDevInfo_t.**/
+    const OCProvisionDev_t *targetDev;          /**< Pointer to OCProvisionDev_t.**/
     OCProvisionResultCB resultCallback;         /**< Pointer to result callback.**/
+    uint16_t credId;                            /**< Trust chain id to be provisioned.**/
     OCProvisionResult_t *resArr;                /**< Result array.**/
     int numOfResults;                           /**< Number of results in result array.**/
-};
+} TrustChainData_t;
+
 
 // Structure to carry get security resource APIs data to callback.
 typedef struct GetSecData GetSecData_t;
@@ -103,6 +134,24 @@ struct GetSecData {
     int numOfResults;                        /**< Number of results in result array.**/
 };
 
+typedef struct GetCsrData GetCsrData_t;
+struct GetCsrData {
+    void *ctx;
+    const OCProvisionDev_t *deviceInfo;         /**< Pointer to PMDevInfo_t.**/
+    OCGetCSRResultCB resultCallback;            /**< Pointer to result callback.**/
+    OCPMGetCsrResult_t *resArr;                 /**< Result array.**/
+    size_t numOfResults;                        /**< Number of results in result array.**/
+};
+
+typedef struct GetRolesData GetRolesData_t;
+struct GetRolesData {
+    void *ctx;                                  /**< User-provided context **/
+    const OCProvisionDev_t *deviceInfo;         /**< Pointer to PMDevInfo_t.**/
+    OCGetRolesResultCB resultCallback;          /**< Pointer to result callback.**/
+    OCPMGetRolesResult_t *resArr;               /**< Result array.**/
+    size_t numOfResults;                        /**< Number of results in result array.**/
+};
+
 /**
  * Structure to carry PCONF provision API data to callback.
  */
@@ -151,30 +200,93 @@ struct RemoveData {
 };
 
 /**
- * Function prototype
+ * Function prototypes
  */
-static OCStackResult provisionCredentials(const OicSecCred_t *cred,
+static OCStackResult ProvisionCredentialsDos(void *ctx, OicSecCred_t *cred,
+        const OCProvisionDev_t *deviceInfo, OCClientResponseHandler responseHandler);
+static OCStackResult provisionCredentials(OicSecCred_t *cred,
         const OCProvisionDev_t *deviceInfo, CredentialData_t *credData,
         OCClientResponseHandler responseHandler);
+static OCStackApplicationResult  ProvisionPskCB(void *ctx, OCDoHandle UNUSED,
+        OCClientResponse *clientResponse);
+static OCStackResult SetDOS(const Data_t *data, OicSecDeviceOnboardingState_t dos,
+                            OCClientResponseHandler resultCallback);
 
+typedef enum {
+    DEVICE_1_FINISHED,
+    DEVICE_2_FINISHED,
+    DEVICE_LOCAL_FINISHED
+} CredProvisioningResultCause_t;
+
+/**
+ * Deallocates a block of memory.
+ *
+ * @param[in] data    Pointer to block of memory previously allocated for Data_t.
+ */
+static void FreeData(Data_t *data)
+{
+    switch (data->type)
+    {
+        case CHAIN_TYPE:
+            {
+                TrustChainData_t *chainData = (TrustChainData_t *) data->ctx;
+                OICFree(chainData->resArr);
+                OICFree(chainData);
+                break;
+            }
+        case ACL_TYPE:
+            {
+                ACLData_t *aclData = (ACLData_t *) data->ctx;
+                OICFree(aclData->resArr);
+                OICFree(aclData);
+                break;
+            }
+        case PSK_TYPE:
+            {
+                CredentialData_t *pskData = (CredentialData_t *) data->ctx;
+                OICFree(pskData->resArr);
+                OICFree(pskData);
+                break;
+            }
+        default:
+            {
+                OIC_LOG_V(INFO, TAG, "Unknown type %d", data->type);
+            }
+    }
+    OICFree(data);
+}
 
 /**
  * Internal function to update result in result array.
  */
 static void registerResultForCredProvisioning(CredentialData_t *credData,
-                                              OCStackResult stackresult, int cause)
+                                              OCStackResult stackresult, CredProvisioningResultCause_t cause)
 {
-
+   OCStackResult res = OC_STACK_ERROR;
    OIC_LOG_V(INFO,TAG,"value of credData->numOfResults is %d",credData->numOfResults);
-   if(1 == cause)
+   switch (cause)
    {
+   case DEVICE_1_FINISHED:
        memcpy(credData->resArr[(credData->numOfResults)].deviceId.id,
-              credData->deviceInfo1->doxm->deviceID.id,UUID_LENGTH);
-   }
-   else
-   {
+              credData->deviceInfo[0]->doxm->deviceID.id,UUID_LENGTH);
+       break;
+   case DEVICE_2_FINISHED:
        memcpy(credData->resArr[(credData->numOfResults)].deviceId.id,
-              credData->deviceInfo2->doxm->deviceID.id,UUID_LENGTH);
+              credData->deviceInfo[1]->doxm->deviceID.id,UUID_LENGTH);
+       break;
+   case DEVICE_LOCAL_FINISHED:
+       res = GetDoxmDeviceID(&credData->resArr[(credData->numOfResults)].deviceId);
+       if (OC_STACK_OK != res)
+       {
+           OIC_LOG_V(WARNING, TAG, "%s: Could not retrieve own device ID to populate result for cred provisioning: %d", __func__, res);
+           memset(credData->resArr[(credData->numOfResults)].deviceId.id, 0, UUID_LENGTH);
+       }
+       break;
+   default:
+       assert(!"Unknown value for cause");
+       OIC_LOG_V(ERROR, TAG, "%s: unknown value of cause: %d", __func__, cause);
+       memset(credData->resArr[(credData->numOfResults)].deviceId.id, 0, UUID_LENGTH);
+       break;
    }
    credData->resArr[(credData->numOfResults)].res = stackresult;
    ++(credData->numOfResults);
@@ -192,7 +304,7 @@ static void registerResultForCredProvisioning(CredentialData_t *credData,
 static OCStackApplicationResult provisionCredentialCB2(void *ctx, OCDoHandle UNUSED,
                                                        OCClientResponse *clientResponse)
 {
-    VERIFY_NON_NULL(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
+    VERIFY_NOT_NULL_RETURN(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
     CredentialData_t *credData = (CredentialData_t *) ctx;
     (void)UNUSED;
 
@@ -202,9 +314,9 @@ static OCStackApplicationResult provisionCredentialCB2(void *ctx, OCDoHandle UNU
     {
         if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
         {
-            registerResultForCredProvisioning(credData, OC_STACK_RESOURCE_CHANGED, 2);
-            OCStackResult res =  PDMLinkDevices(&credData->deviceInfo1->doxm->deviceID,
-                    &credData->deviceInfo2->doxm->deviceID);
+            registerResultForCredProvisioning(credData, OC_STACK_RESOURCE_CHANGED, DEVICE_2_FINISHED);
+            OCStackResult res =  PDMLinkDevices(&credData->deviceInfo[0]->doxm->deviceID,
+                    &credData->deviceInfo[1]->doxm->deviceID);
             if (OC_STACK_OK != res)
             {
                 OIC_LOG(ERROR, TAG, "Error occured on PDMLinkDevices");
@@ -222,7 +334,7 @@ static OCStackApplicationResult provisionCredentialCB2(void *ctx, OCDoHandle UNU
 
     }
     OIC_LOG(INFO, TAG, "provisionCredentialCB2 received Null clientResponse");
-    registerResultForCredProvisioning(credData, OC_STACK_ERROR, 2);
+    registerResultForCredProvisioning(credData, OC_STACK_ERROR, DEVICE_2_FINISHED);
     ((OCProvisionResultCB)(resultCallback))(credData->ctx, credData->numOfResults,
                                             credData->resArr,
                                             true);
@@ -243,22 +355,28 @@ static OCStackApplicationResult provisionCredentialCB2(void *ctx, OCDoHandle UNU
 static OCStackApplicationResult provisionCredentialCB1(void *ctx, OCDoHandle UNUSED,
                                                        OCClientResponse *clientResponse)
 {
-    VERIFY_NON_NULL(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
+    VERIFY_NOT_NULL_RETURN(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
     (void)UNUSED;
     CredentialData_t* credData = (CredentialData_t*) ctx;
-    OICFree(credData->credInfoFirst);
-    const OCProvisionDev_t *deviceInfo = credData->deviceInfo2;
-    OicSecCred_t *credInfo = credData->credInfo;
+    OICFree(credData->credInfo[0]);
+    const OCProvisionDev_t *deviceInfo = credData->deviceInfo[1];
+    OicSecCred_t *credInfo = credData->credInfo[1];
     const OCProvisionResultCB resultCallback = credData->resultCallback;
     if (clientResponse)
     {
         if (OC_STACK_RESOURCE_CHANGED == clientResponse->result)
         {
             // send credentials to second device
-            registerResultForCredProvisioning(credData, OC_STACK_RESOURCE_CHANGED,1);
+            registerResultForCredProvisioning(credData, OC_STACK_RESOURCE_CHANGED, DEVICE_1_FINISHED);
             OCStackResult res = provisionCredentials(credInfo, deviceInfo, credData,
                     provisionCredentialCB2);
-            DeleteCredList(credInfo);
+            // If deviceInfo is NULL, this device is the second device. Don't delete the cred
+            // because provisionCredentials added it to the local cred store and it now owns
+            // the memory.
+            if ((NULL != deviceInfo) || (OC_STACK_OK != res))
+            {
+                DeleteCredList(credInfo);
+            }
             if (OC_STACK_OK != res)
             {
                 registerResultForCredProvisioning(credData, res,2);
@@ -272,7 +390,7 @@ static OCStackApplicationResult provisionCredentialCB1(void *ctx, OCDoHandle UNU
         }
         else
         {
-            registerResultForCredProvisioning(credData, OC_STACK_ERROR,1);
+            registerResultForCredProvisioning(credData, OC_STACK_ERROR, DEVICE_1_FINISHED);
             ((OCProvisionResultCB)(resultCallback))(credData->ctx, credData->numOfResults,
                                                     credData->resArr,
                                                     true);
@@ -284,7 +402,7 @@ static OCStackApplicationResult provisionCredentialCB1(void *ctx, OCDoHandle UNU
     else
     {
         OIC_LOG(INFO, TAG, "provisionCredentialCB received Null clientResponse for first device");
-        registerResultForCredProvisioning(credData, OC_STACK_ERROR,1);
+        registerResultForCredProvisioning(credData, OC_STACK_ERROR, DEVICE_1_FINISHED);
        ((OCProvisionResultCB)(resultCallback))(credData->ctx, credData->numOfResults,
                                                      credData->resArr,
                                                      true);
@@ -296,9 +414,114 @@ static OCStackApplicationResult provisionCredentialCB1(void *ctx, OCDoHandle UNU
     return OC_STACK_DELETE_TRANSACTION;
 }
 
+/**
+ * Callback handler for handling callback of provisioning device 2.
+ *
+ * @param[in] ctx             ctx value passed to callback from calling function.
+ * @param[in] UNUSED          handle to an invocation
+ * @param[in] clientResponse  Response from queries to remote servers.
+ * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
+ *          and  OC_STACK_KEEP_TRANSACTION to keep it.
+ */
+static OCStackApplicationResult ProvisionCredentialDosCB2(void *ctx, OCDoHandle UNUSED,
+                                                       OCClientResponse *clientResponse)
+{
+    VERIFY_NOT_NULL_RETURN(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
+    CredentialData_t *credData = (CredentialData_t *) ((Data_t *) ctx)->ctx;
+    (void)UNUSED;
+
+    OCProvisionResultCB resultCallback = credData->resultCallback;
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+    if (clientResponse)
+    {
+        if (OC_STACK_RESOURCE_CHANGED == clientResponse->result)
+        {
+            registerResultForCredProvisioning(credData, OC_STACK_RESOURCE_CHANGED, DEVICE_2_FINISHED);
+            OCStackResult res =  PDMLinkDevices(&credData->deviceInfo[0]->doxm->deviceID,
+                                                &credData->deviceInfo[1]->doxm->deviceID);
+            if (OC_STACK_OK != res)
+            {
+                OIC_LOG(ERROR, TAG, "Error occured on PDMLinkDevices");
+                return OC_STACK_DELETE_TRANSACTION;
+            }
+            OIC_LOG(INFO, TAG, "Link created successfully");
+
+            ((OCProvisionResultCB)(resultCallback))(credData->ctx, credData->numOfResults,
+                                                    credData->resArr,
+                                                    false);
+            FreeData(ctx);
+            return OC_STACK_DELETE_TRANSACTION;
+        }
 
+    }
+    OIC_LOG(INFO, TAG, "ProvisionCredentialDosCB2 received Null clientResponse");
+    registerResultForCredProvisioning(credData, OC_STACK_ERROR, DEVICE_2_FINISHED);
+    ((OCProvisionResultCB)(resultCallback))(credData->ctx, credData->numOfResults,
+                                            credData->resArr,
+                                            true);
+    FreeData(ctx);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+    return OC_STACK_DELETE_TRANSACTION;
+}
 
 /**
+ * Callback handler for handling callback of provisioning device 1.
+ *
+ * @param[in] ctx             ctx value passed to callback from calling function.
+ * @param[in] UNUSED          handle to an invocation
+ * @param[in] clientResponse  Response from queries to remote servers.
+ * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
+ *          and  OC_STACK_KEEP_TRANSACTION to keep it.
+ */
+static OCStackApplicationResult ProvisionCredentialDosCB1(void *ctx, OCDoHandle UNUSED,
+        OCClientResponse *clientResponse)
+{
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+    VERIFY_NOT_NULL_RETURN(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
+    (void) UNUSED;
+    CredentialData_t *credData = (CredentialData_t *) ((Data_t *) ctx)->ctx;
+    const OCProvisionResultCB resultCallback = credData->resultCallback;
+    if (clientResponse)
+    {
+        if (OC_STACK_RESOURCE_CHANGED == clientResponse->result)
+        {
+            // send credentials to second device
+            registerResultForCredProvisioning(credData, OC_STACK_RESOURCE_CHANGED, DEVICE_1_FINISHED);
+            OCStackResult res = SetDOS((Data_t *) ctx, DOS_RFPRO, ProvisionPskCB);
+            // If deviceInfo is NULL, this device is the second device. Don't delete the cred
+            // because provisionCredentials added it to the local cred store and it now owns
+            // the memory.
+            if (OC_STACK_OK != res)
+            {
+                registerResultForCredProvisioning(credData, res, 2);
+                ((OCProvisionResultCB)(resultCallback))(credData->ctx, credData->numOfResults,
+                                                        credData->resArr,
+                                                        true);
+                FreeData(ctx);
+            }
+        }
+        else
+        {
+            registerResultForCredProvisioning(credData, OC_STACK_ERROR, DEVICE_1_FINISHED);
+            ((OCProvisionResultCB)(resultCallback))(credData->ctx, credData->numOfResults,
+                                                    credData->resArr,
+                                                    true);
+            FreeData(ctx);
+        }
+    }
+    else
+    {
+        OIC_LOG(INFO, TAG, "provisionCredentialCB received Null clientResponse for first device");
+        registerResultForCredProvisioning(credData, OC_STACK_ERROR, DEVICE_1_FINISHED);
+        ((OCProvisionResultCB)(resultCallback))(credData->ctx, credData->numOfResults,
+                                                credData->resArr,
+                                                true);
+        FreeData(ctx);
+    }
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+    return OC_STACK_DELETE_TRANSACTION;
+}
+/**
  * Internal function for handling credential generation and sending credential to resource server.
  *
  * @param[in] cred Instance of cred resource.
@@ -306,118 +529,159 @@ static OCStackApplicationResult provisionCredentialCB1(void *ctx, OCDoHandle UNU
  * @param[in] responseHandler callbak called by OC stack when request API receives response.
  * @return  OC_STACK_OK in case of success and other value otherwise.
  */
-static OCStackResult provisionCredentials(const OicSecCred_t *cred,
+static OCStackResult provisionCredentials(OicSecCred_t *cred,
         const OCProvisionDev_t *deviceInfo, CredentialData_t *credData,
         OCClientResponseHandler responseHandler)
 {
-    OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
-    if (!secPayload)
-    {
-        OIC_LOG(ERROR, TAG, "Failed to memory allocation");
-        return OC_STACK_NO_MEMORY;
-    }
-    secPayload->base.type = PAYLOAD_TYPE_SECURITY;
-    int secureFlag = 0;
-    OCStackResult res = CredToCBORPayload(cred, &secPayload->securityData,
-                                          &secPayload->payloadSize, secureFlag);
-    if((OC_STACK_OK != res) && (NULL == secPayload->securityData))
-    {
-        OCPayloadDestroy((OCPayload *)secPayload);
-        OIC_LOG(ERROR, TAG, "Failed to CredToCBORPayload");
-        return OC_STACK_NO_MEMORY;
-    }
+    OCStackResult res = OC_STACK_OK;
 
-    OIC_LOG(DEBUG, TAG, "Created payload for Cred:");
-    OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
-    char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
-    if(!PMGenerateQuery(true,
-                        deviceInfo->endpoint.addr,
-                        deviceInfo->securePort,
-                        deviceInfo->connType,
-                        query, sizeof(query), OIC_RSRC_CRED_URI))
+    if (NULL != deviceInfo)
     {
-        OIC_LOG(ERROR, TAG, "DeviceDiscoveryHandler : Failed to generate query");
-        return OC_STACK_ERROR;
-    }
-    OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
+        OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
+        if (!secPayload)
+        {
+            OIC_LOG(ERROR, TAG, "Failed to allocate memory");
+            return OC_STACK_NO_MEMORY;
+        }
+        secPayload->base.type = PAYLOAD_TYPE_SECURITY;
+        int secureFlag = 0;
+        res = CredToCBORPayload(cred, &secPayload->securityData, &secPayload->payloadSize, secureFlag);
+        if ((OC_STACK_OK != res) && (NULL == secPayload->securityData))
+        {
+            OCPayloadDestroy((OCPayload *)secPayload);
+            OIC_LOG(ERROR, TAG, "Failed to CredToCBORPayload");
+            return OC_STACK_NO_MEMORY;
+        }
 
-    OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL};
-    cbData.cb = responseHandler;
-    cbData.context = (void *) credData;
-    cbData.cd = NULL;
+        OIC_LOG(DEBUG, TAG, "Created payload for Cred:");
+        OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
+        char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = { 0 };
+        if (!PMGenerateQuery(true,
+            deviceInfo->endpoint.addr,
+            deviceInfo->securePort,
+            deviceInfo->connType,
+            query, sizeof(query), OIC_RSRC_CRED_URI))
+        {
+            OIC_LOG(ERROR, TAG, "DeviceDiscoveryHandler : Failed to generate query");
+            OCPayloadDestroy((OCPayload *)secPayload);
+            return OC_STACK_ERROR;
+        }
+        OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
 
-    OCDoHandle handle = NULL;
-    OCMethod method = OC_REST_POST;
-    OCStackResult ret = OCDoResource(&handle, method, query, 0, (OCPayload*)secPayload,
+        OCCallbackData cbData;
+        memset(&cbData, 0, sizeof(cbData));
+        cbData.cb = responseHandler;
+        cbData.context = (void *)credData;
+        cbData.cd = NULL;
+
+        OCDoHandle handle = NULL;
+        OCMethod method = OC_REST_POST;
+        res = OCDoResource(&handle, method, query, 0, (OCPayload*)secPayload,
             deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
-    OIC_LOG_V(INFO, TAG, "OCDoResource::Credential provisioning returned : %d",ret);
-    if (ret != OC_STACK_OK)
+        OIC_LOG_V(INFO, TAG, "OCDoResource::Credential provisioning returned : %d", res);
+        if (res != OC_STACK_OK)
+        {
+            OIC_LOG(ERROR, TAG, "OCStack resource error");
+            return res;
+        }
+        return OC_STACK_OK;
+    }
+    else
     {
-        OIC_LOG(ERROR, TAG, "OCStack resource error");
-        return ret;
+        /* Provision this credential to the local cred store. On success, the cred resource takes
+         * ownership of the memory. On failure, provisionCredentialCB1 will delete the cred object.
+         */
+        res = AddCredential(cred);
+        /* Call the result callback directly. */
+        registerResultForCredProvisioning(credData, OC_STACK_RESOURCE_CHANGED, DEVICE_LOCAL_FINISHED);
+        (credData->resultCallback)(credData->ctx, credData->numOfResults, credData->resArr, false);
+        return res;
     }
-    return OC_STACK_OK;
 }
-
-#ifdef __WITH_X509__
-/**
- * Structure to carry certificate data to callback.
- */
-typedef struct CertificateData CertData_t;
-struct CertificateData
-{
-    void *ctx;                                  /**< Pointer to user context.**/
-    const OCProvisionDev_t *deviceInfo;        /**< Pointer to OCProvisionDev_t.**/
-    OicSecCred_t *credInfo;                     /**< Pointer to OicSecCred_t.**/
-    OCProvisionResultCB resultCallback;         /**< Pointer to result callback.**/
-    OCProvisionResult_t *resArr;                /**< Result array.**/
-    int numOfResults;                           /**< Number of results in result array.**/
-};
-
 /**
- * Structure to carry CRL provision API data to callback.
+ * Internal function for handling credential generation and sending credential to resource server.
+ *
+ * @param[in] cred Instance of cred resource.
+ * @param[in] deviceInfo information about device to which credential is to be provisioned.
+ * @param[in] responseHandler callbak called by OC stack when request API receives response.
+ * @return  OC_STACK_OK in case of success and other value otherwise.
  */
-typedef struct CRLData CRLData_t;
-struct CRLData
+static OCStackResult ProvisionCredentialsDos(void *ctx, OicSecCred_t *cred,
+        const OCProvisionDev_t *deviceInfo, OCClientResponseHandler responseHandler)
 {
-    void *ctx;                                  /**< Pointer to user context.**/
-    const OCProvisionDev_t *deviceInfo;         /**< Pointer to PMDevInfo_t.**/
-    OCProvisionResultCB resultCallback;         /**< Pointer to result callback.**/
-    OCProvisionResult_t *resArr;                /**< Result array.**/
-    int numOfResults;                           /**< Number of results in result array.**/
-};
+    OCStackResult res = OC_STACK_OK;
+    CredentialData_t *credData = (CredentialData_t *) ((Data_t *) ctx)->ctx;
 
-/**
- * Internal function to update result in result array.
- */
-static void registerResultForCertProvisioning(CertData_t *certData,
-                                              OCStackResult stackresult)
-{
+    if (NULL != deviceInfo)
+    {
+        OCSecurityPayload *secPayload = (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
+        if (!secPayload)
+        {
+            OIC_LOG(ERROR, TAG, "Failed to allocate memory");
+            return OC_STACK_NO_MEMORY;
+        }
+        secPayload->base.type = PAYLOAD_TYPE_SECURITY;
+        int secureFlag = 0;
+        res = CredToCBORPayload(cred, &secPayload->securityData, &secPayload->payloadSize, secureFlag);
+        if ((OC_STACK_OK != res) && (NULL == secPayload->securityData))
+        {
+            OCPayloadDestroy((OCPayload *)secPayload);
+            OIC_LOG(ERROR, TAG, "Failed to CredToCBORPayload");
+            return OC_STACK_NO_MEMORY;
+        }
 
-   OIC_LOG_V(INFO,TAG,"value of credData->numOfResults is %d",certData->numOfResults);
-   memcpy(certData->resArr[(certData->numOfResults)].deviceId.id,
-          certData->deviceInfo->doxm->deviceID.id,UUID_LENGTH);
-   certData->resArr[(certData->numOfResults)].res = stackresult;
-   ++(certData->numOfResults);
+        OIC_LOG(DEBUG, TAG, "Created payload for Cred:");
+        OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
+        char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = { 0 };
+        if (!PMGenerateQuery(true,
+                             deviceInfo->endpoint.addr,
+                             deviceInfo->securePort,
+                             deviceInfo->connType,
+                             query, sizeof(query), OIC_RSRC_CRED_URI))
+        {
+            OIC_LOG(ERROR, TAG, "DeviceDiscoveryHandler : Failed to generate query");
+            OCPayloadDestroy((OCPayload *)secPayload);
+            return OC_STACK_ERROR;
+        }
+        OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
+
+        OCCallbackData cbData = { .context = NULL, .cb = NULL, .cd = NULL };
+        cbData.cb = responseHandler;
+        cbData.context = ctx;
+        cbData.cd = NULL;
+
+        OCDoHandle handle = NULL;
+        OCMethod method = OC_REST_POST;
+        res = OCDoResource(&handle, method, query, 0, (OCPayload *)secPayload,
+                           deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
+        OIC_LOG_V(INFO, TAG, "OCDoResource::Credential provisioning returned : %d", res);
+        if (res != OC_STACK_OK)
+        {
+            OIC_LOG(ERROR, TAG, "OCStack resource error");
+            return res;
+        }
+        return OC_STACK_OK;
+    }
+    else
+    {
+        /* Provision this credential to the local cred store. On success, the cred resource takes
+         * ownership of the memory. On failure, ProvisionCredentialDosCB1 will delete the cred object.
+         */
+        res = AddCredential(cred);
+        /* Call the result callback directly. */
+        registerResultForCredProvisioning(credData, OC_STACK_RESOURCE_CHANGED, DEVICE_LOCAL_FINISHED);
+        (credData->resultCallback)(credData->ctx, credData->numOfResults, credData->resArr, false);
+        return res;
+    }
 }
 
 /**
- * Internal Function to store results in result array during ACL provisioning.
+ * Updates result in result array of the target device.
  */
-static void registerResultForCRLProvisioning(CRLData_t *crlData,
-                                             OCStackResult stackresult)
-{
-   OIC_LOG_V(INFO, TAG, "Inside registerResultForCRLProvisioning crlData->numOfResults is %d\n",
-                       crlData->numOfResults);
-   memcpy(crlData->resArr[(crlData->numOfResults)].deviceId.id,
-          crlData->deviceInfo->doxm->deviceID.id, UUID_LENGTH);
-   crlData->resArr[(crlData->numOfResults)].res = stackresult;
-   ++(crlData->numOfResults);
-}
-
-
+static void RegisterProvResult(const OCProvisionDev_t *targetDev, OCProvisionResult_t *resArr,
+                               int *numOfResults, OCStackResult stackResult);
 /**
- * Callback handler of SRPProvisionCRL.
+ * Callback handler for handling callback of posting DOS_RFNOP.
  *
  * @param[in] ctx             ctx value passed to callback from calling function.
  * @param[in] UNUSED          handle to an invocation
@@ -425,243 +689,668 @@ static void registerResultForCRLProvisioning(CRLData_t *crlData,
  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
  */
-static OCStackApplicationResult SRPProvisionCRLCB(void *ctx, OCDoHandle UNUSED,
-                                                  OCClientResponse *clientResponse)
+static OCStackApplicationResult SetReadyForNormalOperationCB(void *ctx, OCDoHandle handler,
+        OCClientResponse *clientResponse)
 {
-    OIC_LOG_V(INFO, TAG, "Inside SRPProvisionCRLCB.");
-    (void)UNUSED;
-    VERIFY_NON_NULL(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
-    CRLData_t *crlData = (CRLData_t*)ctx;
-    OCProvisionResultCB resultCallback = crlData->resultCallback;
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+    VERIFY_NOT_NULL_RETURN(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
+    DataType_t dataType = ((Data_t *) ctx)->type;
 
-    if (clientResponse)
+    OCProvisionResultCB resultCallback = NULL;
+    const OCProvisionDev_t *targetDev = NULL;
+    OCProvisionResult_t *resArr = NULL;
+    int *numOfResults = NULL;
+
+    void *dataCtx = NULL;
+    OIC_LOG_V(DEBUG, TAG, "Data type %d", dataType);
+
+    switch (dataType)
     {
-        if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
+        case CHAIN_TYPE:
         {
-            registerResultForCRLProvisioning(crlData, OC_STACK_RESOURCE_CHANGED);
-            ((OCProvisionResultCB)(resultCallback))(crlData->ctx, crlData->numOfResults,
-                                                    crlData->resArr,
-                                                    false);
-             OICFree(crlData->resArr);
-             OICFree(crlData);
-             return OC_STACK_DELETE_TRANSACTION;
+            TrustChainData_t *chainData = (TrustChainData_t *) ((Data_t *) ctx)->ctx;
+            resultCallback = chainData->resultCallback;
+            targetDev = chainData->targetDev;
+            resArr = chainData->resArr;
+            numOfResults = &(chainData->numOfResults);
+            dataCtx = chainData->ctx;
+            break;
+        }
+        case ACL_TYPE:
+        {
+            ACLData_t *aclData = (ACLData_t *) ((Data_t *) ctx)->ctx;
+            resultCallback = aclData->resultCallback;
+            targetDev = aclData->deviceInfo;
+            resArr = aclData->resArr;
+            numOfResults = &(aclData->numOfResults);
+            dataCtx = aclData->ctx;
+            break;
+        }
+        case PSK_TYPE:
+        {
+            CredentialData_t *pskData = (CredentialData_t *) ((Data_t *) ctx)->ctx;
+            resArr = pskData->resArr;
+            numOfResults = &(pskData->numOfResults);
+            dataCtx = pskData->ctx;
+            OIC_LOG_V(DEBUG, TAG, "PSK index %d", pskData->currIndex);
+            break;
+        }
+        case CERT_TYPE:
+        {
+            OIC_LOG_V(ERROR, TAG, "Not implemented type %d", dataType);
+            OIC_LOG_V(ERROR, TAG, "OUT %s", __func__);
+            return OC_STACK_DELETE_TRANSACTION;
+        }
+        default:
+        {
+            OIC_LOG_V(ERROR, TAG, "Unknown type %d", dataType);
+            OIC_LOG_V(ERROR, TAG, "OUT %s", __func__);
+            return OC_STACK_DELETE_TRANSACTION;
         }
     }
-    registerResultForCRLProvisioning(crlData, OC_STACK_ERROR);
-    ((OCProvisionResultCB)(resultCallback))(crlData->ctx, crlData->numOfResults,
-                                            crlData->resArr,
-                                            true);
-    OIC_LOG_V(ERROR, TAG, "SRPProvisionCRLCB received Null clientResponse");
-    OICFree(crlData->resArr);
-    OICFree(crlData);
+
+    if (dataType != PSK_TYPE)
+    {
+        RegisterProvResult(targetDev, resArr, numOfResults, clientResponse->result);
+        resultCallback(dataCtx, *numOfResults, resArr, clientResponse->result != OC_STACK_RESOURCE_CHANGED);
+        FreeData(ctx);
+    }
+    else
+    {
+        CredentialData_t *pskData = (CredentialData_t *) ((Data_t *) ctx)->ctx;
+        if (pskData->currIndex == 0)
+        {
+            pskData->currIndex = 1;
+            ProvisionCredentialDosCB1(ctx, handler, clientResponse);
+        }
+        else
+        {
+            ProvisionCredentialDosCB2(ctx, handler, clientResponse);
+        }
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_DELETE_TRANSACTION;
 }
 
-OCStackResult SRPProvisionCRL(void *ctx, const OCProvisionDev_t *selectedDeviceInfo,
-        OicSecCrl_t *crl, OCProvisionResultCB resultCallback)
+/**
+ * Updates pstat resource of server.
+ */
+static OCStackResult SetDOS(const Data_t *data, OicSecDeviceOnboardingState_t dos,
+                            OCClientResponseHandler resultCallback)
 {
-    VERIFY_NON_NULL(TAG, selectedDeviceInfo, ERROR,  OC_STACK_INVALID_PARAM);
-    VERIFY_NON_NULL(TAG, crl, ERROR,  OC_STACK_INVALID_PARAM);
-    VERIFY_NON_NULL(TAG, resultCallback, ERROR,  OC_STACK_INVALID_CALLBACK);
-
-    OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
-    if (!secPayload)
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+    if (NULL == data || NULL == resultCallback)
     {
-        OIC_LOG(ERROR, TAG, "Failed to memory allocation");
-        return OC_STACK_NO_MEMORY;
+        OIC_LOG(ERROR, TAG, "NULL parameters");
+        OIC_LOG_V(ERROR, TAG, "OUT %s", __func__);
+        return OC_STACK_INVALID_PARAM;
     }
 
-    secPayload->base.type = PAYLOAD_TYPE_SECURITY;
-    OCStackResult res = CrlToCBORPayload(crl, &secPayload->securityData, &secPayload->payloadSize);
-    if((OC_STACK_OK != res) && (NULL == secPayload->securityData))
-    {
-        OICFree(secPayload);
-        OIC_LOG(ERROR, TAG, "Failed to BinToCrlJSON");
-        return OC_STACK_NO_MEMORY;
-    }
-    OIC_LOG(DEBUG, TAG, "Created payload for CRL:");
-    OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
 
-    char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
-    if(!PMGenerateQuery(true,
-                        selectedDeviceInfo->endpoint.addr,
-                        selectedDeviceInfo->securePort,
-                        selectedDeviceInfo->connType,
-                        query, sizeof(query), OIC_RSRC_CRL_URI))
+    const OCProvisionDev_t *pTargetDev = NULL;
+
+    switch (data->type)
     {
-        OIC_LOG(ERROR, TAG, "DeviceDiscoveryHandler : Failed to generate query");
-        OCPayloadDestroy((OCPayload *)secPayload);
-        return OC_STACK_ERROR;
+        case CHAIN_TYPE:
+        {
+            pTargetDev = ((TrustChainData_t *)data->ctx)->targetDev;
+            break;
+        }
+        case ACL_TYPE:
+        {
+            pTargetDev = ((ACLData_t *)data->ctx)->deviceInfo;
+            break;
+        }
+        case PSK_TYPE:
+        {
+            CredentialData_t *credData = ((CredentialData_t *)data)->ctx;
+            pTargetDev = credData->deviceInfo[credData->currIndex];
+            break;
+        }
+        case CERT_TYPE:
+        {
+            // TODO check cert provision flow
+            OIC_LOG_V(ERROR, TAG, "Not implemented type: %d", data->type);
+            return OC_STACK_INVALID_PARAM;
+        }
+        default:
+        {
+            OIC_LOG_V(ERROR, TAG, "Unknown type: %d", data->type);
+            return OC_STACK_INVALID_PARAM;
+        }
     }
-    OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
 
-    OCCallbackData cbData =  {.context=NULL, .cb=NULL, .cd=NULL};
-    cbData.cb = &SRPProvisionCRLCB;
-    CRLData_t *crlData = (CRLData_t *) OICCalloc(1, sizeof(CRLData_t));
-    if (crlData == NULL)
+    OCStackResult res = OC_STACK_ERROR;
+    OicSecPstat_t *pstat = (OicSecPstat_t *) OICCalloc(1, sizeof(OicSecPstat_t));
+    if (!pstat)
     {
-        OCPayloadDestroy((OCPayload *)secPayload);
-        OIC_LOG(ERROR, TAG, "Unable to allocate memory");
+        OIC_LOG(ERROR, TAG, "Failed to allocate memory");
         return OC_STACK_NO_MEMORY;
     }
 
-    crlData->deviceInfo = selectedDeviceInfo;
-    crlData->resultCallback = resultCallback;
-    crlData->numOfResults=0;
-    crlData->ctx = ctx;
+    pstat->dos.state = dos;
 
-    crlData->resArr = (OCProvisionResult_t*)OICCalloc(1, sizeof(OCProvisionResult_t));
-    if (crlData->resArr == NULL)
+    OCSecurityPayload *secPayload = (OCSecurityPayload *) OICCalloc(1, sizeof(OCSecurityPayload));
+    if (!secPayload)
     {
-        OCPayloadDestroy((OCPayload *)secPayload);
-        OIC_LOG(ERROR, TAG, "Unable to allocate memory");
-        return OC_STACK_NO_MEMORY;
+        OIC_LOG(ERROR, TAG, "Failed to allocate memory");
+        res = OC_STACK_NO_MEMORY;
+        goto error;
     }
+    secPayload->base.type = PAYLOAD_TYPE_SECURITY;
 
-    cbData.context = (void *)crlData;
-    cbData.cd = NULL;
+    // Note [IOT-2052] all the POST payloads in the provisioningclient app
+    // should be updated to use the Partial payload APIs for the SVRs, so they
+    // do not include read-only Properties for the Server device current
+    // state.
+    bool propertiesToInclude[PSTAT_PROPERTY_COUNT] = {false};
+    propertiesToInclude[PSTAT_DOS] = true;
+
+    if (OC_STACK_OK != PstatToCBORPayloadPartial(pstat, &(secPayload->securityData),
+            &(secPayload->payloadSize), propertiesToInclude))
+    {
+        OCPayloadDestroy((OCPayload *) secPayload);
+        OIC_LOG(ERROR, TAG, "Failed to PstatToCBORPayload");
+        res = OC_STACK_NO_MEMORY;
+        goto error;
+    }
+    OIC_LOG(DEBUG, TAG, "Created payload for pstat set");
+    OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
+
+    char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
+    if (!PMGenerateQuery(true,
+                         pTargetDev->endpoint.addr,
+                         pTargetDev->securePort,
+                         pTargetDev->connType,
+                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
+    {
+        OIC_LOG(ERROR, TAG, "Failed to generate query");
+        OCPayloadDestroy((OCPayload *) secPayload);
+        res = OC_STACK_ERROR;
+        goto error;
+    }
+    OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
+
+    OCCallbackData cbData = { .context = NULL, .cb = NULL, .cd = NULL };
     OCMethod method = OC_REST_POST;
     OCDoHandle handle = NULL;
-    OIC_LOG(DEBUG, TAG, "Sending CRL info to resource server");
+    OCProvisionDev_t *targetDev = NULL;
 
-    OCStackResult ret = OCDoResource(&handle, method, query,
-            &selectedDeviceInfo->endpoint, (OCPayload*)secPayload,
-            selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
+    targetDev = PMCloneOCProvisionDev(pTargetDev);
 
-    if (ret != OC_STACK_OK)
+    if (NULL == targetDev)
+    {
+        OIC_LOG(ERROR, TAG, "target dev is null");
+        res = OC_STACK_ERROR;
+        goto error;
+    }
+    cbData.cb = resultCallback;
+    cbData.context = (void *) data;
+    cbData.cd = NULL;
+    OIC_LOG(DEBUG, TAG, "Sending PSTAT info to resource server");
+    res = OCDoResource(&handle, method, query,
+                       &targetDev->endpoint, (OCPayload *)secPayload,
+                       targetDev->connType, OC_HIGH_QOS, &cbData, NULL, 0);
+    if (OC_STACK_OK != res)
     {
-        OICFree(crlData->resArr);
-        OICFree(crlData);
+        OIC_LOG(ERROR, TAG, "OCStack resource error");
     }
 
-    return ret;
+error:
+    OICFree(pstat);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+    return res;
 }
 
 /**
- * Internal function for handling credential generation and sending cretificate credential.
- *
- * @param[in] cred Instance of cred resource.
- * @param[in] deviceInfo information about device to which credential is to be provisioned.
- * @param[in] responseHandler callbak called by OC stack when request API receives response.
- * @return  OC_STACK_OK in case of success and other value otherwise.
+ * Restores pstat after provisioning.
  */
-static OCStackResult provisionCertCred(const OicSecCred_t *cred,
-        const OCProvisionDev_t *deviceInfo, CertData_t *certData,
-        OCClientResponseHandler responseHandler)
+static OCStackApplicationResult ProvisionCB(void *ctx, OCDoHandle UNUSED,
+        OCClientResponse *clientResponse)
 {
-    OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
-    if(!secPayload)
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+    VERIFY_NOT_NULL_RETURN(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
+    (void) UNUSED;
+    if (clientResponse && OC_STACK_RESOURCE_CHANGED != clientResponse->result)
     {
-        OIC_LOG(ERROR, TAG, "Failed to memory allocation");
-        return OC_STACK_NO_MEMORY;
+        OIC_LOG_V(ERROR, TAG, "Responce result: %d", clientResponse->result);
     }
-    secPayload->base.type = PAYLOAD_TYPE_SECURITY;
-    int secureFlag = 0;
-    OCStackResult res = CredToCBORPayload(cred, &secPayload->securityData,
-        &secPayload->payloadSize, secureFlag);
+    if (OC_STACK_OK != SetDOS(ctx, DOS_RFNOP, SetReadyForNormalOperationCB))
+    {
+        OIC_LOG_V(ERROR, TAG, "OUT %s", __func__);
+        return OC_STACK_DELETE_TRANSACTION;
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+    return OC_STACK_DELETE_TRANSACTION;
+}
+/**
+ * Callback for PSK provisioning.
+ */
+static OCStackApplicationResult  ProvisionPskCB(void *ctx, OCDoHandle UNUSED,
+                                                OCClientResponse *clientResponse)
+{
+    VERIFY_NOT_NULL_RETURN(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
+    (void) UNUSED;
+    CredentialData_t *credData = (CredentialData_t *) ((Data_t *) ctx)->ctx;
+    const OCProvisionDev_t *device = credData->deviceInfo[credData->currIndex];
+    OicSecCred_t *cred = credData->credInfo[credData->currIndex];
+    const OCProvisionResultCB resultCallback = credData->resultCallback;
 
-    if ((OC_STACK_OK != res) || (NULL == secPayload->securityData))
+    if (clientResponse)
     {
-        OICFree(secPayload);
-        OIC_LOG(ERROR, TAG, "Failed to CredToCBORPayload");
-        return OC_STACK_NO_MEMORY;
+        if (OC_STACK_RESOURCE_CHANGED == clientResponse->result)
+        {
+            OCStackResult res = ProvisionCredentialsDos(ctx, cred, device, ProvisionCB);
+            if (OC_STACK_OK != res)
+            {
+                registerResultForCredProvisioning(credData, res, 2);
+                ((OCProvisionResultCB)(resultCallback))(credData->ctx, credData->numOfResults,
+                                                        credData->resArr, true);
+                FreeData(ctx);
+                return OC_STACK_DELETE_TRANSACTION;
+            }
+        }
+        else
+        {
+            registerResultForCredProvisioning(credData, OC_STACK_ERROR, credData->currIndex);
+            ((OCProvisionResultCB)(resultCallback))(credData->ctx, credData->numOfResults,
+                                                    credData->resArr,
+                                                    true);
+            FreeData(ctx);
+        }
+    }
+    else
+    {
+        OIC_LOG(INFO, TAG, "provisionCredentialCB received Null clientResponse for first device");
+        registerResultForCredProvisioning(credData, OC_STACK_ERROR, credData->currIndex);
+        ((OCProvisionResultCB)(resultCallback))(credData->ctx, credData->numOfResults,
+                                                credData->resArr,
+                                                true);
+        FreeData(ctx);
+        credData = NULL;
     }
+    return OC_STACK_DELETE_TRANSACTION;
+}
 
-    OIC_LOG(DEBUG, TAG, "Created payload for Cred:");
-    OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
-    char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
-    if(!PMGenerateQuery(true,
-                        deviceInfo->endpoint.addr,
-                        deviceInfo->securePort,
-                        deviceInfo->connType,
-                        query, sizeof(query), OIC_RSRC_CRED_URI))
+
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+/**
+ * Structure to carry certificate data to callback.
+ */
+typedef struct CertificateData CertData_t;
+struct CertificateData
+{
+    void *ctx;                                  /**< Pointer to user context.**/
+    const OCProvisionDev_t *deviceInfo;        /**< Pointer to OCProvisionDev_t.**/
+    OicSecCred_t *credInfo;                     /**< Pointer to OicSecCred_t.**/
+    OCProvisionResultCB resultCallback;         /**< Pointer to result callback.**/
+    OCProvisionResult_t *resArr;                /**< Result array.**/
+    int numOfResults;                           /**< Number of results in result array.**/
+};
+
+OCStackResult SRPRegisterTrustCertChainNotifier(void *ctx, TrustCertChainChangeCB callback)
+{
+    if (g_trustCertChainNotifier.callback)
     {
-        OIC_LOG(ERROR, TAG, "DeviceDiscoveryHandler : Failed to generate query");
-        OCPayloadDestroy((OCPayload *)secPayload);
+        OIC_LOG(ERROR, TAG, "Can't register Notifier, Unregister previous one");
         return OC_STACK_ERROR;
     }
-    OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
 
-    OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL};
-    cbData.cb = responseHandler;
-    cbData.context = (void *) certData;
-    cbData.cd = NULL;
+    g_trustCertChainNotifier.callback = callback;
+    g_trustCertChainNotifier.context = ctx;
+    return OC_STACK_OK;
+}
 
-    OCDoHandle handle = NULL;
-    OCMethod method = OC_REST_POST;
-    OCStackResult ret = OCDoResource(&handle, method, query, 0, (OCPayload*)secPayload,
-            deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
-    OIC_LOG_V(INFO, TAG, "OCDoResource::Certificate provisioning returned : %d",ret);
-    if (ret != OC_STACK_OK)
+void SRPRemoveTrustCertChainNotifier()
+{
+    g_trustCertChainNotifier.callback = NULL;
+    g_trustCertChainNotifier.context = NULL;
+    return;
+}
+
+static OCStackApplicationResult provisionCertificateCB(void *ctx, OCDoHandle UNUSED,
+    OCClientResponse *clientResponse)
+{
+    // Just call the callback provided to SRProvisionCredentials
+    VERIFY_NOT_NULL_RETURN(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
+    CredentialData_t* credData = (CredentialData_t *)ctx;
+    (void)UNUSED;
+    bool hasError;
+
+    // We expect OC_STACK_RESOURCE_CHANGED, anything else is an error
+    if (clientResponse && (OC_STACK_RESOURCE_CHANGED == clientResponse->result))
     {
-        OIC_LOG(ERROR, TAG, "OCStack resource error");
+        hasError = false;
+    }
+    else
+    {
+        hasError = true;
     }
 
-    return ret;
-}
+    OCProvisionResultCB resultCallback = credData->resultCallback;
+    VERIFY_NOT_NULL_RETURN(TAG, resultCallback, ERROR, OC_STACK_DELETE_TRANSACTION);
 
+    ((OCProvisionResultCB)(resultCallback))(credData->ctx, credData->numOfResults,
+        credData->resArr, hasError);
+
+    OICFree(credData);
+
+    return OC_STACK_DELETE_TRANSACTION;
+
+}
 /**
- * Callback handler for handling callback of certificate provisioning device.
- *
- * @param[in] ctx             ctx value passed to callback from calling function.
- * @param[in] UNUSED          handle to an invocation
- * @param[in] clientResponse  Response from queries to remote servers.
- * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
- *          and  OC_STACK_KEEP_TRANSACTION to keep it.
+ * Callback for Trust Chain provisioning.
  */
-static OCStackApplicationResult provisionCertCB(void *ctx, OCDoHandle UNUSED,
-                                                       OCClientResponse *clientResponse)
+static OCStackApplicationResult ProvisionTrustChainCB(void *ctx, OCDoHandle UNUSED,
+        OCClientResponse *clientResponse)
 {
-    VERIFY_NON_NULL(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
-    CertData_t *certData = (CertData_t *) ctx;
-    (void)UNUSED;
-
-    OCProvisionResultCB resultCallback = certData->resultCallback;
-    OIC_LOG(INFO, TAG, "provisionCertCred called");
-    if (clientResponse)
+    OIC_LOG_V(INFO, TAG, "IN %s", __func__);
+    (void) UNUSED;
+    if (NULL == ctx)
     {
-        if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
+        OIC_LOG(ERROR, TAG, "Context is NULL");
+        return OC_STACK_INVALID_PARAM;
+    }
+    if (OC_STACK_RESOURCE_CHANGED == clientResponse->result)
+    {
+        Data_t *data = (Data_t *) ctx;
+        if (CHAIN_TYPE != data->type)
         {
-            registerResultForCertProvisioning(certData, OC_STACK_RESOURCE_CHANGED);
-            ((OCProvisionResultCB)(resultCallback))(certData->ctx, certData->numOfResults,
-                                                    certData->resArr,
-                                                    false);
-             OICFree(certData->resArr);
-             OICFree(certData);
-             return OC_STACK_DELETE_TRANSACTION;
+            OIC_LOG(ERROR, TAG, "Invalid type");
+            return OC_STACK_INVALID_PARAM;
+        }
+        TrustChainData_t *chainData = (TrustChainData_t *) (data->ctx);
+        OicSecCred_t *trustCertChainCred = GetCredEntryByCredId(chainData->credId);
+        if (NULL == trustCertChainCred)
+        {
+            OIC_LOG(ERROR, TAG, "Can not find matched Trust Cert. Chain.");
+            return OC_STACK_NO_RESOURCE;
         }
 
+        OCSecurityPayload *secPayload = (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
+        if (!secPayload)
+        {
+            DeleteCredList(trustCertChainCred);
+            OIC_LOG(ERROR, TAG, "Failed to allocate memory");
+            return OC_STACK_NO_MEMORY;
+        }
+        secPayload->base.type = PAYLOAD_TYPE_SECURITY;
+        int secureFlag = 1; /* Don't send the private key to the device, if it happens to be present */
+        if (OC_STACK_OK != CredToCBORPayload(trustCertChainCred, &secPayload->securityData,
+                                             &secPayload->payloadSize, secureFlag))
+        {
+            DeleteCredList(trustCertChainCred);
+            OCPayloadDestroy((OCPayload *)secPayload);
+            OIC_LOG(ERROR, TAG, "Failed to CredToCBORPayload");
+            return OC_STACK_NO_MEMORY;
+        }
+        DeleteCredList(trustCertChainCred);
+        OIC_LOG(DEBUG, TAG, "Created payload for Cred:");
+        OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
+
+        char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
+        if (!PMGenerateQuery(true,
+                             chainData->targetDev->endpoint.addr,
+                             chainData->targetDev->securePort,
+                             chainData->targetDev->connType,
+                             query, sizeof(query), OIC_RSRC_CRED_URI))
+        {
+            OIC_LOG(ERROR, TAG, "Failed to generate query");
+            OCPayloadDestroy((OCPayload *)secPayload);
+            return OC_STACK_ERROR;
+        }
+        OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
+
+        OCCallbackData cbData =  {.context = NULL, .cb = NULL, .cd = NULL};
+        cbData.cb = ProvisionCB;
+        cbData.context = ctx;
+        cbData.cd = NULL;
+        OCMethod method = OC_REST_POST;
+        OCDoHandle handle = NULL;
+        OIC_LOG(DEBUG, TAG, "Sending Cred info to resource server");
+        OCStackResult ret = OCDoResource(&handle, method, query,
+                                         &chainData->targetDev->endpoint, (OCPayload *)secPayload,
+                                         chainData->targetDev->connType, OC_HIGH_QOS, &cbData, NULL, 0);
+        if (ret != OC_STACK_OK)
+        {
+            OIC_LOG_V(INFO, TAG, "OUT %s", __func__);
+            return ret;
+        }
     }
-    OIC_LOG(INFO, TAG, "provisionCertCredCB received Null clientResponse");
-    registerResultForCertProvisioning(certData, OC_STACK_ERROR);
-    ((OCProvisionResultCB)(resultCallback))(certData->ctx, certData->numOfResults,
-                                            certData->resArr,
-                                            true);
-    OICFree(certData->resArr);
-    OICFree(certData);
-    return OC_STACK_DELETE_TRANSACTION;
+    else
+    {
+        OIC_LOG_V(ERROR, TAG, "OUT %s", __func__);
+        return OC_STACK_ERROR;
+    }
+
+    OIC_LOG_V(INFO, TAG, "OUT %s", __func__);
+    return OC_STACK_OK;
 }
-#endif // __WITH_X509__
+
+OCStackResult SRPProvisionTrustCertChain(void *ctx, OicSecCredType_t type, uint16_t credId,
+        const OCProvisionDev_t *selectedDeviceInfo, OCProvisionResultCB resultCallback)
+{
+    OIC_LOG_V(INFO, TAG, "IN %s", __func__);
+    VERIFY_NOT_NULL_RETURN(TAG, selectedDeviceInfo, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NOT_NULL_RETURN(TAG, resultCallback, ERROR,  OC_STACK_INVALID_CALLBACK);
+    if (SIGNED_ASYMMETRIC_KEY != type)
+    {
+        OIC_LOG(INFO, TAG, "Invalid key type");
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    TrustChainData_t *chainData = (TrustChainData_t *) OICCalloc(1, sizeof(TrustChainData_t));
+    if (NULL == chainData)
+    {
+        OIC_LOG(ERROR, TAG, "Memory allocation problem");
+        return OC_STACK_NO_MEMORY;
+    }
+    chainData->targetDev = selectedDeviceInfo;
+    chainData->resultCallback = resultCallback;
+    chainData->credId = credId;
+    chainData->ctx = ctx;
+    chainData->numOfResults = 0;
+
+    int noOfRiCalls = 1;
+    chainData->resArr = (OCProvisionResult_t *)OICCalloc(noOfRiCalls, sizeof(OCProvisionResult_t));
+    if (chainData->resArr == NULL)
+    {
+        OICFree(chainData);
+        OIC_LOG(ERROR, TAG, "Unable to allocate memory");
+        return OC_STACK_NO_MEMORY;
+    }
+
+    Data_t *data = (Data_t *) OICCalloc(1, sizeof(Data_t));
+    data->type = CHAIN_TYPE;
+    data->ctx = chainData;
+
+    if (SetDOS(data, DOS_RFPRO, ProvisionTrustChainCB) != OC_STACK_OK)
+    {
+        FreeData(data);
+        OIC_LOG_V(INFO, TAG, "OUT %s", __func__);
+        return OC_STACK_ERROR;
+    }
+
+    OIC_LOG_V(INFO, TAG, "OUT %s", __func__);
+    return OC_STACK_OK;
+}
+
+OCStackResult SRPSaveTrustCertChain(const uint8_t *trustCertChain, size_t chainSize,
+                                            OicEncodingType_t encodingType, uint16_t *credId)
+{
+    OIC_LOG(DEBUG, TAG, "IN SRPSaveTrustCertChain");
+    VERIFY_NOT_NULL_RETURN(TAG, trustCertChain, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NOT_NULL_RETURN(TAG, credId, ERROR,  OC_STACK_INVALID_PARAM);
+
+    OCStackResult res = OC_STACK_ERROR;
+
+    OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(*cred));
+    VERIFY_NOT_NULL_RETURN(TAG, cred, ERROR, OC_STACK_NO_MEMORY);
+
+    res = GetDoxmDeviceID(&cred->subject);
+    if (OC_STACK_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "Can't get the device id(GetDoxmDeviceID)");
+        DeleteCredList(cred);
+        return res;
+    }
+
+    cred->credUsage= (char *)OICCalloc(1, strlen(TRUST_CA) + 1);
+    VERIFY_NOT_NULL_RETURN(TAG, cred->credUsage, ERROR, OC_STACK_NO_MEMORY);
+    OICStrcpy(cred->credUsage, strlen(TRUST_CA) + 1, TRUST_CA);
+
+    cred->credType = SIGNED_ASYMMETRIC_KEY;
+
+    if (encodingType == OIC_ENCODING_PEM)
+    {
+        cred->optionalData.data = (uint8_t *)OICCalloc(1, chainSize + 1);
+        VERIFY_NOT_NULL_RETURN(TAG, cred->optionalData.data, ERROR, OC_STACK_NO_MEMORY);
+        cred->optionalData.len = chainSize + 1;
+    }
+    else if (encodingType == OIC_ENCODING_DER)
+    {
+        cred->optionalData.data = (uint8_t *)OICCalloc(1, chainSize);
+        VERIFY_NOT_NULL_RETURN(TAG, cred->optionalData.data, ERROR, OC_STACK_NO_MEMORY);
+        cred->optionalData.len = chainSize;
+    }
+    else
+    {
+        OIC_LOG_V(ERROR, TAG, "Unknown encoding in %s", __func__);
+        DeleteCredList(cred);
+        return OC_STACK_INVALID_PARAM;
+    }
+    memcpy(cred->optionalData.data, trustCertChain, chainSize);
+    cred->optionalData.encoding = encodingType;
+    cred->optionalData.revstat = false;
+
+    res = AddCredential(cred);
+    if(res != OC_STACK_OK)
+    {
+        DeleteCredList(cred);
+        return res;
+    }
+    *credId = cred->credId;
+
+    if (g_trustCertChainNotifier.callback)
+    {
+        uint8_t *certChain = (uint8_t*)OICCalloc(1, sizeof(uint8_t) * chainSize);
+        VERIFY_NOT_NULL_RETURN(TAG, certChain, ERROR, OC_STACK_NO_MEMORY);
+        memcpy(certChain, trustCertChain, chainSize);
+        g_trustCertChainNotifier.callback(g_trustCertChainNotifier.context, *credId,
+                certChain, chainSize);
+        OICFree(certChain);
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT SRPSaveTrustCertChain");
+
+    return res;
+}
+
+static OCStackResult saveCertChain(OicSecKey_t * cert, OicSecKey_t * key, uint16_t *credId, const char* usage)
+{
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+    VERIFY_NOT_NULL_RETURN(TAG, cert, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NOT_NULL_RETURN(TAG, cert->data, ERROR,  OC_STACK_INVALID_PARAM);
+
+    VERIFY_NOT_NULL_RETURN(TAG, credId, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NOT_NULL_RETURN(TAG, usage, ERROR, OC_STACK_INVALID_PARAM);
+
+    if (NULL == key && PRIMARY_CERT == usage)
+    {
+        OIC_LOG_V(ERROR, TAG, "Key is NULL, but it is mandatory if usage is %s", PRIMARY_CERT);
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    if (key != NULL)
+    {
+        /* Key is optional. */
+        VERIFY_NOT_NULL_RETURN(TAG, key->data, ERROR, OC_STACK_INVALID_PARAM);
+    }
+
+    OCStackResult res = OC_STACK_ERROR;
+
+    OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(*cred));
+    VERIFY_NOT_NULL_RETURN(TAG, cred, ERROR, OC_STACK_NO_MEMORY);
+
+    OIC_LOG_V(DEBUG, TAG, "IN: %s", __func__);
+
+    res = GetDoxmDeviceID(&cred->subject);
+    if (OC_STACK_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "Can't get the device id(GetDoxmDeviceID)");
+        DeleteCredList(cred);
+        return res;
+    }
+
+    cred->credUsage= (char *)OICCalloc(1, strlen(usage) + 1);
+    VERIFY_NOT_NULL_RETURN(TAG, cred->credUsage, ERROR, OC_STACK_NO_MEMORY);
+    OICStrcpy(cred->credUsage, strlen(usage) + 1, usage);
+
+    cred->credType = SIGNED_ASYMMETRIC_KEY;
+
+    OicSecKey_t *publicData = &cred->publicData;
+    publicData->data = (uint8_t *)OICCalloc(1, cert->len);
+    VERIFY_NOT_NULL_RETURN(TAG, publicData->data, ERROR, OC_STACK_NO_MEMORY);
+    memcpy(publicData->data, cert->data, cert->len);
+    publicData->len = cert->len;
+    publicData->encoding = cert->encoding;
+
+    if (key != NULL)
+    {
+        OicSecKey_t *privateData = &cred->privateData;
+        privateData->data = (uint8_t *)OICCalloc(1, key->len);
+        VERIFY_NOT_NULL_RETURN(TAG, privateData->data, ERROR, OC_STACK_NO_MEMORY);
+        memcpy(privateData->data, key->data, key->len);
+        privateData->len = key->len;
+        privateData->encoding = key->encoding;
+    }
+
+    res = AddCredential(cred);
+    if(res != OC_STACK_OK)
+    {
+        DeleteCredList(cred);
+        return res;
+    }
+    *credId = cred->credId;
+
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+
+    return res;
+}
+
+OCStackResult SRPSaveOwnCertChain(OicSecKey_t * cert, OicSecKey_t * key, uint16_t *credId)
+{
+    return saveCertChain(cert, key, credId, PRIMARY_CERT);
+}
+
+OCStackResult SRPSaveOwnRoleCert(OicSecKey_t * cert, uint16_t *credId)
+{
+    return saveCertChain(cert, NULL, credId, ROLE_CERT);
+}
+
+#endif // __WITH_DTLS__ || __WITH_TLS__
 
 OCStackResult SRPProvisionCredentials(void *ctx, OicSecCredType_t type, size_t keySize,
                                       const OCProvisionDev_t *pDev1,
                                       const OCProvisionDev_t *pDev2,
+                                      const char* pemCert,
+                                      const OicSecRole_t *role1,
+                                      const OicSecRole_t *role2,
                                       OCProvisionResultCB resultCallback)
 {
-    VERIFY_NON_NULL(TAG, pDev1, ERROR,  OC_STACK_INVALID_PARAM);
-    if (SYMMETRIC_PAIR_WISE_KEY == type)
-    {
-        VERIFY_NON_NULL(TAG, pDev2, ERROR,  OC_STACK_INVALID_PARAM);
-    }
+    VERIFY_NOT_NULL_RETURN(TAG, pDev1, ERROR,  OC_STACK_INVALID_PARAM);
     if (!resultCallback)
     {
-        OIC_LOG(INFO, TAG, "SRPUnlinkDevices : NULL Callback");
+        OIC_LOG(INFO, TAG, "SRPProvisionCredentials: NULL Callback");
         return OC_STACK_INVALID_CALLBACK;
     }
-    if (SYMMETRIC_PAIR_WISE_KEY == type &&
-        0 == memcmp(&pDev1->doxm->deviceID, &pDev2->doxm->deviceID, sizeof(OicUuid_t)))
+    if ((SYMMETRIC_PAIR_WISE_KEY == type) &&
+        (NULL != pDev2) &&
+        (0 == memcmp(&pDev1->doxm->deviceID, &pDev2->doxm->deviceID, sizeof(OicUuid_t))))
     {
-        OIC_LOG(INFO, TAG, "SRPUnlinkDevices : Same device ID");
+        OIC_LOG(INFO, TAG, "SRPProvisionCredentials : Same device ID");
         return OC_STACK_INVALID_PARAM;
     }
 
@@ -674,7 +1363,7 @@ OCStackResult SRPProvisionCredentials(void *ctx, OicSecCredType_t type, size_t k
 
     OIC_LOG(INFO, TAG, "In SRPProvisionCredentials");
 
-    if (SYMMETRIC_PAIR_WISE_KEY == type)
+    if ((SYMMETRIC_PAIR_WISE_KEY == type) && (NULL != pDev2))
     {
         bool linkExisits = true;
         OCStackResult res = PDMIsLinkExists(&pDev1->doxm->deviceID, &pDev2->doxm->deviceID, &linkExisits);
@@ -708,9 +1397,10 @@ OCStackResult SRPProvisionCredentials(void *ctx, OicSecCredType_t type, size_t k
             OicSecCred_t *firstCred = NULL;
             OicSecCred_t *secondCred = NULL;
             OCStackResult res = PMGeneratePairWiseCredentials(type, keySize, &provTooldeviceID,
-                    &firstDevice->doxm->deviceID, &secondDevice->doxm->deviceID,
+                    &firstDevice->doxm->deviceID, (NULL != secondDevice) ? &secondDevice->doxm->deviceID : &provTooldeviceID,
+                    role1, role2,
                     &firstCred, &secondCred);
-            VERIFY_SUCCESS(TAG, (res==OC_STACK_OK), ERROR, OC_STACK_ERROR);
+            VERIFY_SUCCESS_RETURN(TAG, (res==OC_STACK_OK), ERROR, OC_STACK_ERROR);
             OIC_LOG(INFO, TAG, "Credentials generated successfully");
             CredentialData_t *credData =
                 (CredentialData_t *) OICCalloc(1, sizeof(CredentialData_t));
@@ -721,11 +1411,11 @@ OCStackResult SRPProvisionCredentials(void *ctx, OicSecCredType_t type, size_t k
                 OIC_LOG(ERROR, TAG, "Memory allocation problem");
                 return OC_STACK_NO_MEMORY;
             }
-            credData->deviceInfo1 = firstDevice;
-            credData->deviceInfo2 = secondDevice;
-            credData->credInfo = secondCred;
+            credData->deviceInfo[0] = firstDevice;
+            credData->deviceInfo[1] = secondDevice;
+            credData->credInfo[1] = secondCred;
             credData->ctx = ctx;
-            credData->credInfoFirst = firstCred;
+            credData->credInfo[0] = firstCred;
             credData->numOfResults = 0;
             credData->resultCallback = resultCallback;
             // first call to provision creds to device1.
@@ -750,192 +1440,274 @@ OCStackResult SRPProvisionCredentials(void *ctx, OicSecCredType_t type, size_t k
                 OICFree(credData);
             }
             OIC_LOG_V(INFO, TAG, "provisionCredentials returned: %d",res);
-            VERIFY_SUCCESS(TAG, (res==OC_STACK_OK), ERROR, OC_STACK_ERROR);
+            VERIFY_SUCCESS_RETURN(TAG, (res==OC_STACK_OK), ERROR, OC_STACK_ERROR);
             return res;
         }
-#ifdef __WITH_X509__
         case SIGNED_ASYMMETRIC_KEY:
         {
-            const OCProvisionDev_t *firstDevice = pDev1;
-            OicSecCred_t *cred = NULL;
-            OCStackResult res = PMGenerateCertificateCredentials(&provTooldeviceID,
-                                                                &firstDevice->doxm->deviceID,&cred);
-            VERIFY_SUCCESS(TAG, (res==OC_STACK_OK), ERROR, OC_STACK_ERROR);
-            OIC_LOG(INFO, TAG, "Certificate credentials generated successfully");
-            CertData_t *certData = (CertData_t *) OICCalloc(1, sizeof(CertData_t));
-            if (NULL == certData)
+            /* pDev1 is the device to be provisioned, checked non-null above */
+            /* pDev2 is not used, should be NULL */
+            /* size param is not used. */
+            /* pemCert is the cerficiate to be provisioned */
+            VERIFY_NOT_NULL_RETURN(TAG, pemCert, ERROR, OC_STACK_INVALID_PARAM);
+
+            OicSecKey_t deviceCert = { 0 };
+            deviceCert.data = (uint8_t*) pemCert; /* Casting away const is OK here */
+            deviceCert.len = strlen(pemCert) + 1;
+            deviceCert.encoding = OIC_ENCODING_PEM;
+
+            /* Create a credential object */
+            OicSecCred_t* cred =  GenerateCredential(&pDev1->doxm->deviceID, SIGNED_ASYMMETRIC_KEY,
+                    &deviceCert, NULL, // oic.sec.cred.publicdata = deviceCert, .privatedata = NULL
+                    &provTooldeviceID, NULL); // rowner is the provisioning tool and no eowner
+            VERIFY_NOT_NULL_RETURN(TAG, cred, ERROR, OC_STACK_ERROR);
+
+            cred->publicData.encoding = OIC_ENCODING_PEM;
+
+            if (OCInternalIsValidRoleCertificate(deviceCert.data, deviceCert.len, NULL, NULL) == OC_STACK_OK)
             {
-                OICFree(cred);
-                OIC_LOG(ERROR, TAG, "Memory allocation problem");
-                return OC_STACK_NO_MEMORY;
+                cred->credUsage = OICStrdup(ROLE_CERT);
+            }
+            else
+            {
+                cred->credUsage = OICStrdup(PRIMARY_CERT);
             }
 
-            certData->deviceInfo = firstDevice;
-            certData->ctx = ctx;
-            certData->credInfo = cred;
-            certData->numOfResults = 0;
-            certData->resultCallback = resultCallback;
-
-            certData->resArr = (OCProvisionResult_t*)OICCalloc(1, sizeof(OCProvisionResult_t));
-            if (NULL == certData->resArr)
+            /* Create credential data (used by the response handler provisionCertificateCB and freed there) */
+            CredentialData_t *credData = (CredentialData_t *)OICCalloc(1, sizeof(CredentialData_t));
+            if ((NULL == credData) || (NULL == cred->credUsage))
             {
                 DeleteCredList(cred);
-                OICFree(certData);
                 OIC_LOG(ERROR, TAG, "Memory allocation problem");
                 return OC_STACK_NO_MEMORY;
             }
+            credData->deviceInfo[0] = pDev1;
+            credData->deviceInfo[1] = NULL;
+            credData->credInfo[1] = cred;
+            credData->ctx = ctx;
+            credData->credInfo[0] = cred;
+            credData->numOfResults = 0;
+            credData->resultCallback = resultCallback;
+            credData->resArr = NULL;
 
-            res = provisionCertCred(cred, firstDevice, certData, &provisionCertCB);
-            if (OC_STACK_OK != res)
+            /* Note: the callback is of type OCClientResponseHandler, thin wrapper that calls resultCallback */
+            OCStackResult res = provisionCredentials(cred, pDev1, credData, &provisionCertificateCB);
+            if (res != OC_STACK_OK)
             {
-                OICFree(certData->resArr);
-                OICFree(certData);
+                OICFree(credData);
             }
-            DeleteCredList(cred);
-            OIC_LOG_V(INFO, TAG, "provisionCertCredentials returned: %d",res);
 
-            return res;
+            DeleteCredList(cred);
+            return OC_STACK_OK;
         }
-#endif
         default:
         {
             OIC_LOG(ERROR, TAG, "Invalid option.");
             return OC_STACK_INVALID_PARAM;
         }
     }
-    return OC_STACK_ERROR;
 }
 
-/**
- * Internal Function to store results in result array during ACL provisioning.
- */
-static void registerResultForACLProvisioning(ACLData_t *aclData,
-                                             OCStackResult stackresult)
+OCStackResult SRPProvisionCredentialsDos(void *ctx, OicSecCredType_t type, size_t keySize,
+                                      const OCProvisionDev_t *pDev1,
+                                      const OCProvisionDev_t *pDev2,
+                                      OCProvisionResultCB resultCallback)
 {
-   OIC_LOG_V(INFO, TAG, "Inside registerResultForACLProvisioning aclData->numOfResults is %d\n",
-                       aclData->numOfResults);
-   memcpy(aclData->resArr[(aclData->numOfResults)].deviceId.id,
-          aclData->deviceInfo->doxm->deviceID.id, UUID_LENGTH);
-   aclData->resArr[(aclData->numOfResults)].res = stackresult;
-   ++(aclData->numOfResults);
-}
+    VERIFY_NOT_NULL_RETURN(TAG, pDev1, ERROR,  OC_STACK_INVALID_PARAM);
+    if (!resultCallback)
+    {
+        OIC_LOG(INFO, TAG, "SRPProvisionCredentialsDos: NULL Callback");
+        return OC_STACK_INVALID_CALLBACK;
+    }
+    if ((SYMMETRIC_PAIR_WISE_KEY == type) &&
+        (NULL != pDev2) &&
+        (0 == memcmp(&pDev1->doxm->deviceID, &pDev2->doxm->deviceID, sizeof(OicUuid_t))))
+    {
+        OIC_LOG(INFO, TAG, "SRPProvisionCredentialsDos : Same device ID");
+        return OC_STACK_INVALID_PARAM;
+    }
+    if (SYMMETRIC_PAIR_WISE_KEY == type && NULL == pDev2)
+    {
+        OIC_LOG(INFO, TAG, "SRPProvisionCredentialsDos : NULL device");
+        return OC_STACK_INVALID_PARAM;
+    }
 
-/**
- * Callback handler of SRPProvisionACL.
- *
- * @param[in] ctx             ctx value passed to callback from calling function.
- * @param[in] UNUSED          handle to an invocation
- * @param[in] clientResponse  Response from queries to remote servers.
- * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
- *          and  OC_STACK_KEEP_TRANSACTION to keep it.
- */
-static OCStackApplicationResult SRPProvisionACLCB(void *ctx, OCDoHandle UNUSED,
-                                                  OCClientResponse *clientResponse)
-{
-    OIC_LOG_V(INFO, TAG, "Inside SRPProvisionACLCB.");
-    (void)UNUSED;
-    VERIFY_NON_NULL(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
-    ACLData_t *aclData = (ACLData_t*)ctx;
-    OCProvisionResultCB resultCallback = aclData->resultCallback;
+    if (SYMMETRIC_PAIR_WISE_KEY == type &&
+       !(OWNER_PSK_LENGTH_128 == keySize || OWNER_PSK_LENGTH_256 == keySize))
+    {
+        OIC_LOG(INFO, TAG, "Invalid key size");
+        return OC_STACK_INVALID_PARAM;
+    }
 
-    if (clientResponse)
+    OIC_LOG(INFO, TAG, "In SRPProvisionCredentialsDos");
+
+    if ((SYMMETRIC_PAIR_WISE_KEY == type) && (NULL != pDev2))
     {
-        if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
+        bool linkExisits = true;
+        OCStackResult res = PDMIsLinkExists(&pDev1->doxm->deviceID, &pDev2->doxm->deviceID, &linkExisits);
+
+        if (res != OC_STACK_OK)
         {
-            registerResultForACLProvisioning(aclData, OC_STACK_RESOURCE_CHANGED);
-            ((OCProvisionResultCB)(resultCallback))(aclData->ctx, aclData->numOfResults,
-                                                    aclData->resArr,
-                                                    false);
-             OICFree(aclData->resArr);
-             OICFree(aclData);
-             return OC_STACK_DELETE_TRANSACTION;
+            OIC_LOG(ERROR, TAG, "Internal error occured");
+            return res;
+        }
+        if (linkExisits)
+        {
+            OIC_LOG(ERROR, TAG, "Link already exists");
+            return OC_STACK_INVALID_PARAM;
         }
     }
-    registerResultForACLProvisioning(aclData, OC_STACK_ERROR);
-    ((OCProvisionResultCB)(resultCallback))(aclData->ctx, aclData->numOfResults,
-                                            aclData->resArr,
-                                            true);
-    OIC_LOG_V(ERROR, TAG, "SRPProvisionACLCB received Null clientResponse");
-    OICFree(aclData->resArr);
-    OICFree(aclData);
-    return OC_STACK_DELETE_TRANSACTION;
-}
 
-OCStackResult SRPProvisionACL(void *ctx, const OCProvisionDev_t *selectedDeviceInfo,
-        OicSecAcl_t *acl, OCProvisionResultCB resultCallback)
-{
-    VERIFY_NON_NULL(TAG, selectedDeviceInfo, ERROR,  OC_STACK_INVALID_PARAM);
-    VERIFY_NON_NULL(TAG, acl, ERROR,  OC_STACK_INVALID_PARAM);
-    VERIFY_NON_NULL(TAG, resultCallback, ERROR,  OC_STACK_INVALID_CALLBACK);
-
-    OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
-    if(!secPayload)
+    OicUuid_t provTooldeviceID =   {{0,}};
+    if (OC_STACK_OK != GetDoxmDeviceID(&provTooldeviceID))
     {
-        OIC_LOG(ERROR, TAG, "Failed to memory allocation");
-        return OC_STACK_NO_MEMORY;
+        OIC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID");
+        return OC_STACK_ERROR;
     }
-    secPayload->base.type = PAYLOAD_TYPE_SECURITY;
-    if(OC_STACK_OK != AclToCBORPayload(acl, &secPayload->securityData, &secPayload->payloadSize))
+    OIC_LOG(INFO, TAG, "retrieved deviceid");
+
+    CredentialData_t *credData = (CredentialData_t *) OICCalloc(1, sizeof(CredentialData_t));
+    Data_t *data = (Data_t *) OICCalloc(1, sizeof(Data_t));
+    if (NULL == credData || NULL == data)
     {
-        OCPayloadDestroy((OCPayload *)secPayload);
-        OIC_LOG(ERROR, TAG, "Failed to AclToCBORPayload");
+
+        OICFree(credData);
+        OICFree(data);
+        OIC_LOG(ERROR, TAG, "Memory allocation problem");
         return OC_STACK_NO_MEMORY;
     }
-    OIC_LOG(DEBUG, TAG, "Created payload for ACL:");
-    OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
 
-    char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
-    if(!PMGenerateQuery(true,
-                        selectedDeviceInfo->endpoint.addr,
-                        selectedDeviceInfo->securePort,
-                        selectedDeviceInfo->connType,
-                        query, sizeof(query), OIC_RSRC_ACL_URI))
+    data->ctx = credData;
+
+    switch (type)
     {
-        OIC_LOG(ERROR, TAG, "DeviceDiscoveryHandler : Failed to generate query");
-        return OC_STACK_ERROR;
+        case SYMMETRIC_PAIR_WISE_KEY:
+        {
+            data->type = PSK_TYPE;
+            OicSecCred_t *firstCred = NULL;
+            OicSecCred_t *secondCred = NULL;
+            OCStackResult res = PMGeneratePairWiseCredentials(type, keySize, &provTooldeviceID,
+                                &pDev1->doxm->deviceID, (NULL != pDev2) ? &pDev2->doxm->deviceID :
+                                &provTooldeviceID,
+                                NULL, NULL,
+                                &firstCred, &secondCred);
+            VERIFY_SUCCESS_RETURN(TAG, (res == OC_STACK_OK), ERROR, OC_STACK_ERROR);
+            OIC_LOG(INFO, TAG, "Credentials generated successfully");
+
+            credData->deviceInfo[0] = pDev1;
+            credData->deviceInfo[1] = pDev2;
+            credData->credInfo[0] = firstCred;
+            credData->credInfo[1] = secondCred;
+            credData->ctx = ctx;
+            credData->currIndex = 0;
+            credData->numOfResults = 0;
+            credData->resultCallback = resultCallback;
+            // first call to provision creds to device1.
+            // second call to provision creds to device2.
+            int noOfRiCalls = 2;
+            credData->resArr =
+                (OCProvisionResult_t *)OICCalloc(noOfRiCalls, sizeof(OCProvisionResult_t));
+            if (NULL == credData->resArr)
+            {
+                OICFree(firstCred);
+                OICFree(secondCred);
+                OICFree(credData);
+                OIC_LOG(ERROR, TAG, "Memory allocation problem");
+                return OC_STACK_NO_MEMORY;
+            }
+
+            res = SetDOS(data, DOS_RFPRO, ProvisionPskCB);
+
+            if (OC_STACK_OK != res)
+            {
+                DeleteCredList(firstCred);
+                DeleteCredList(secondCred);
+                FreeData(data);
+                OIC_LOG_V(ERROR, TAG, "OUT %s", __func__);
+                return res;
+            }
+            OIC_LOG_V(INFO, TAG, "provisionCredentials returned: %d", res);
+            return res;
+        }
+        default:
+        {
+            OIC_LOG(ERROR, TAG, "Invalid option.");
+            return OC_STACK_INVALID_PARAM;
+        }
     }
-    OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
+}
+/**
+ * Callback for ACL provisioning.
+ */
+static OCStackApplicationResult ProvisionAclCB(void *ctx, OCDoHandle UNUSED,
+        OCClientResponse *clientResponse);
+
+OCStackResult SRPProvisionACL(void *ctx, const OCProvisionDev_t *selectedDeviceInfo,
+        OicSecAcl_t *acl, OicSecAclVersion_t aclVersion, OCProvisionResultCB resultCallback)
+{
+    VERIFY_NOT_NULL_RETURN(TAG, selectedDeviceInfo, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NOT_NULL_RETURN(TAG, acl, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NOT_NULL_RETURN(TAG, resultCallback, ERROR,  OC_STACK_INVALID_CALLBACK);
+    OIC_LOG_V(INFO, TAG, "IN %s", __func__);
+
 
-    OCCallbackData cbData =  {.context=NULL, .cb=NULL, .cd=NULL};
-    cbData.cb = &SRPProvisionACLCB;
     ACLData_t *aclData = (ACLData_t *) OICCalloc(1, sizeof(ACLData_t));
-    if (aclData == NULL)
+    if (NULL == aclData)
     {
-        OCPayloadDestroy((OCPayload *)secPayload);
-        OIC_LOG(ERROR, TAG, "Unable to allocate memory");
+        OIC_LOG(ERROR, TAG, "Memory allocation problem");
+        OIC_LOG_V(ERROR, TAG, "OUT %s", __func__);
         return OC_STACK_NO_MEMORY;
     }
     aclData->deviceInfo = selectedDeviceInfo;
     aclData->resultCallback = resultCallback;
-    aclData->numOfResults=0;
+    aclData->aclVersion = aclVersion;
+    aclData->acl = acl;
     aclData->ctx = ctx;
-    // call to provision ACL to device1.
-    int noOfRiCalls = 1;
-    aclData->resArr = (OCProvisionResult_t*)OICCalloc(noOfRiCalls, sizeof(OCProvisionResult_t));
+    aclData->numOfResults = 0;
+
+    aclData->resArr = (OCProvisionResult_t *) OICCalloc(1, sizeof(OCProvisionResult_t));
     if (aclData->resArr == NULL)
     {
         OICFree(aclData);
-        OCPayloadDestroy((OCPayload *)secPayload);
         OIC_LOG(ERROR, TAG, "Unable to allocate memory");
+        OIC_LOG_V(ERROR, TAG, "OUT %s", __func__);
         return OC_STACK_NO_MEMORY;
     }
-    cbData.context = (void *)aclData;
-    cbData.cd = NULL;
-    OCMethod method = OC_REST_POST;
-    OCDoHandle handle = NULL;
-    OIC_LOG(DEBUG, TAG, "Sending ACL info to resource server");
-    OCStackResult ret = OCDoResource(&handle, method, query,
-            &selectedDeviceInfo->endpoint, (OCPayload*)secPayload,
-            selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
-    if (ret != OC_STACK_OK)
+
+    Data_t *data = (Data_t *) OICCalloc(1, sizeof(Data_t));
+    if (data == NULL)
     {
         OICFree(aclData->resArr);
         OICFree(aclData);
+        OIC_LOG(ERROR, TAG, "Unable to allocate memory");
+        OIC_LOG_V(ERROR, TAG, "OUT %s", __func__);
+        return OC_STACK_NO_MEMORY;
+    }
+    data->type = ACL_TYPE;
+    data->ctx = aclData;
+
+    if (SetDOS(data, DOS_RFPRO, ProvisionAclCB) != OC_STACK_OK)
+    {
+        FreeData(data);
+        OIC_LOG_V(ERROR, TAG, "OUT %s", __func__);
+        return OC_STACK_ERROR;
     }
-    VERIFY_SUCCESS(TAG, (OC_STACK_OK == ret), ERROR, OC_STACK_ERROR);
+
+    OIC_LOG_V(INFO, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
 
+OCStackResult SRPSaveACL(const OicSecAcl_t *acl)
+{
+    OIC_LOG(DEBUG, TAG, "IN SRPSaveACL");
+    VERIFY_NOT_NULL_RETURN(TAG, acl, ERROR,  OC_STACK_INVALID_PARAM);
+
+    OCStackResult res =  InstallACL(acl);
+
+    OIC_LOG(DEBUG, TAG, "OUT SRPSaveACL");
+    return res;
+}
+
 /**
  * Internal Function to store results in result array during Direct-Pairing provisioning.
  */
@@ -943,7 +1715,7 @@ static void registerResultForDirectPairingProvisioning(PconfData_t *pconfData,
                                              OCStackResult stackresult)
 {
    OIC_LOG_V(INFO, TAG, "Inside registerResultForDirectPairingProvisioning "
-           "pconfData->numOfResults is %d\n", pconfData->numOfResults);
+           "pconfData->numOfResults is %d", pconfData->numOfResults);
    memcpy(pconfData->resArr[(pconfData->numOfResults)].deviceId.id,
           pconfData->deviceInfo->doxm->deviceID.id, UUID_LENGTH);
    pconfData->resArr[(pconfData->numOfResults)].res = stackresult;
@@ -964,7 +1736,7 @@ static OCStackApplicationResult SRPProvisionDirectPairingCB(void *ctx, OCDoHandl
 {
     OIC_LOG_V(INFO, TAG, "Inside SRPProvisionDirectPairingCB.");
     (void)UNUSED;
-    VERIFY_NON_NULL(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
+    VERIFY_NOT_NULL_RETURN(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
     PconfData_t *pconfData = (PconfData_t*)ctx;
     OCProvisionResultCB resultCallback = pconfData->resultCallback;
 
@@ -994,9 +1766,9 @@ static OCStackApplicationResult SRPProvisionDirectPairingCB(void *ctx, OCDoHandl
 OCStackResult SRPProvisionDirectPairing(void *ctx, const OCProvisionDev_t *selectedDeviceInfo,
         OicSecPconf_t *pconf, OCProvisionResultCB resultCallback)
 {
-    VERIFY_NON_NULL(TAG, selectedDeviceInfo, ERROR,  OC_STACK_INVALID_PARAM);
-    VERIFY_NON_NULL(TAG, pconf, ERROR,  OC_STACK_INVALID_PARAM);
-    VERIFY_NON_NULL(TAG, resultCallback, ERROR,  OC_STACK_INVALID_CALLBACK);
+    VERIFY_NOT_NULL_RETURN(TAG, selectedDeviceInfo, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NOT_NULL_RETURN(TAG, pconf, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NOT_NULL_RETURN(TAG, resultCallback, ERROR,  OC_STACK_INVALID_CALLBACK);
 
     // check direct-pairing capability
     if (true != selectedDeviceInfo->doxm->dpc)
@@ -1016,7 +1788,7 @@ OCStackResult SRPProvisionDirectPairing(void *ctx, const OCProvisionDev_t *selec
     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
     if(!secPayload)
     {
-        OIC_LOG(ERROR, TAG, "Failed to memory allocation");
+        OIC_LOG(ERROR, TAG, "Failed to allocate memory");
         return OC_STACK_NO_MEMORY;
     }
     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
@@ -1031,7 +1803,6 @@ OCStackResult SRPProvisionDirectPairing(void *ctx, const OCProvisionDev_t *selec
     OIC_LOG(DEBUG, TAG, "Created payload for pconf set");
     OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
 
-
     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
     if(!PMGenerateQuery(true,
                 selectedDeviceInfo->endpoint.addr,
@@ -1080,7 +1851,7 @@ OCStackResult SRPProvisionDirectPairing(void *ctx, const OCProvisionDev_t *selec
         OICFree(pconfData->resArr);
         OICFree(pconfData);
     }
-    VERIFY_SUCCESS(TAG, (OC_STACK_OK == ret), ERROR, OC_STACK_ERROR);
+    VERIFY_SUCCESS_RETURN(TAG, (OC_STACK_OK == ret), ERROR, OC_STACK_ERROR);
     return OC_STACK_OK;
 }
 
@@ -1099,7 +1870,7 @@ static void registerResultForUnlinkDevices(UnlinkData_t *unlinkData, OCStackResu
 {
     if (NULL != unlinkData)
     {
-        OIC_LOG_V(INFO, TAG, "Inside registerResultForUnlinkDevices unlinkData->numOfResults is %d\n",
+        OIC_LOG_V(INFO, TAG, "Inside registerResultForUnlinkDevices unlinkData->numOfResults is %d",
                             unlinkData->numOfResults);
         OIC_LOG_V(INFO, TAG, "Stack result :: %d", stackresult);
 
@@ -1136,31 +1907,42 @@ static OCStackResult SendDeleteCredentialRequest(void* ctx,
     OCStackResult ret = ConvertUuidToStr(&revokedDev->doxm->deviceID, &subID);
     if(OC_STACK_OK != ret)
     {
-        OIC_LOG(ERROR, TAG, "SendDeleteCredentialRequest : Failed to canonical UUID encoding");
+        OIC_LOG(ERROR, TAG, "SendDeleteCredentialRequest : Failed to canonical UUID encoding");
+        return OC_STACK_ERROR;
+    }
+
+    char addressEncoded[CA_MAX_URI_LENGTH] = {0};
+    OCStackResult result = OCEncodeAddressForRFC6874(addressEncoded,
+                                                     sizeof(addressEncoded),
+                                                     destDev->endpoint.addr);
+    if (OC_STACK_OK != result)
+    {
+        OIC_LOG_V(ERROR, TAG, "SendDeleteCredentialRequest : encoding error %d", result);
         return OC_STACK_ERROR;
     }
 
     char reqBuf[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
     int snRet = 0;
                     //coaps://0.0.0.0:5684/oic/sec/cred?subjectid=(Canonical ENCODED UUID)
-    char *srpUri = SRP_FORM_DELETE_CREDENTIAL;
+    const char *srpUri = SRP_FORM_DELETE_CREDENTIAL;
 #ifdef __WITH_TLS__
-    if(CA_ADAPTER_TCP == destDev->endpoint.adapter)
+    if((int)CA_ADAPTER_TCP == (int)destDev->endpoint.adapter)
     {
         srpUri = SRP_FORM_DELETE_CREDENTIAL_TCP;
     }
 #endif
-    snRet = snprintf(reqBuf, sizeof(reqBuf), srpUri, destDev->endpoint.addr,
+
+    snRet = snprintf(reqBuf, sizeof(reqBuf), srpUri, addressEncoded,
                      destDev->securePort, OIC_RSRC_CRED_URI, OIC_JSON_SUBJECTID_NAME, subID);
     OICFree(subID);
     if (snRet < 0)
     {
-        OIC_LOG_V(ERROR, TAG, "SendDeleteCredentialRequest : Error (snprintf) %d\n", snRet);
+        OIC_LOG_V(ERROR, TAG, "SendDeleteCredentialRequest : Error (snprintf) %d", snRet);
         return OC_STACK_ERROR;
     }
     else if ((size_t)snRet >= sizeof(reqBuf))
     {
-        OIC_LOG_V(ERROR, TAG, "SendDeleteCredentialRequest : Truncated (snprintf) %d\n", snRet);
+        OIC_LOG_V(ERROR, TAG, "SendDeleteCredentialRequest : Truncated (snprintf) %d", snRet);
         return OC_STACK_ERROR;
     }
 
@@ -1205,20 +1987,30 @@ static OCStackResult SendDeleteACLRequest(void* ctx,
         return OC_STACK_ERROR;
     }
 
+    char addressEncoded[CA_MAX_URI_LENGTH] = {0};
+    OCStackResult result = OCEncodeAddressForRFC6874(addressEncoded,
+                                                     sizeof(addressEncoded),
+                                                     destDev->endpoint.addr);
+    if (OC_STACK_OK != result)
+    {
+        OIC_LOG_V(ERROR, TAG, "SendDeleteCredentialRequest : encoding error %d", result);
+        return OC_STACK_ERROR;
+    }
+
     char reqBuf[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
     int snRet = 0;
                     //coaps://0.0.0.0:5684/oic/sec/acl?subjectuuid=(Canonical ENCODED UUID)
-    snRet = snprintf(reqBuf, sizeof(reqBuf), SRP_FORM_DELETE_CREDENTIAL, destDev->endpoint.addr,
-                     destDev->securePort, OIC_RSRC_ACL_URI, OIC_JSON_SUBJECTID_NAME, subID);
+    snRet = snprintf(reqBuf, sizeof(reqBuf), SRP_FORM_DELETE_CREDENTIAL, addressEncoded,
+                     destDev->securePort, OIC_RSRC_ACL2_URI, OIC_JSON_SUBJECTID_NAME, subID);
     OICFree(subID);
     if (snRet < 0)
     {
-        OIC_LOG_V(ERROR, TAG, "SendDeleteACLRequest : Error (snprintf) %d\n", snRet);
+        OIC_LOG_V(ERROR, TAG, "SendDeleteACLRequest : Error (snprintf) %d", snRet);
         return OC_STACK_ERROR;
     }
     else if ((size_t)snRet >= sizeof(reqBuf))
     {
-        OIC_LOG_V(ERROR, TAG, "SendDeleteACLRequest : Truncated (snprintf) %d\n", snRet);
+        OIC_LOG_V(ERROR, TAG, "SendDeleteACLRequest : Truncated (snprintf) %d", snRet);
         return OC_STACK_ERROR;
     }
 
@@ -1257,7 +2049,7 @@ static OCStackApplicationResult SRPUnlinkDevice2CB(void *unlinkCtx, OCDoHandle h
 {
     (void) handle;
     OIC_LOG(DEBUG, TAG, "IN SRPUnlinkDevice2CB");
-    VERIFY_NON_NULL(TAG, unlinkCtx, ERROR, OC_STACK_DELETE_TRANSACTION);
+    VERIFY_NOT_NULL_RETURN(TAG, unlinkCtx, ERROR, OC_STACK_DELETE_TRANSACTION);
     UnlinkData_t* unlinkData = (UnlinkData_t*)unlinkCtx;
 
     if (clientResponse)
@@ -1320,7 +2112,7 @@ static OCStackApplicationResult SRPUnlinkDevice1CB(void *unlinkCtx, OCDoHandle h
         OCClientResponse *clientResponse)
 {
     OIC_LOG_V(INFO, TAG, "Inside SRPUnlinkDevice1CB ");
-    VERIFY_NON_NULL(TAG, unlinkCtx, ERROR, OC_STACK_DELETE_TRANSACTION);
+    VERIFY_NOT_NULL_RETURN(TAG, unlinkCtx, ERROR, OC_STACK_DELETE_TRANSACTION);
     UnlinkData_t* unlinkData = (UnlinkData_t*)unlinkCtx;
     (void) handle;
 
@@ -1426,7 +2218,7 @@ OCStackResult SRPUnlinkDevices(void* ctx,
     }
 
     UnlinkData_t* unlinkData = (UnlinkData_t*)OICCalloc(1, sizeof(UnlinkData_t));
-    VERIFY_NON_NULL(TAG, unlinkData, ERROR, OC_STACK_NO_MEMORY);
+    VERIFY_NOT_NULL_RETURN(TAG, unlinkData, ERROR, OC_STACK_NO_MEMORY);
 
     //Initialize unlink data
     unlinkData->ctx = ctx;
@@ -1482,7 +2274,7 @@ static void DeleteRemoveData_t(RemoveData_t* pRemoveData)
 static void registerResultForRemoveDevice(RemoveData_t *removeData, OicUuid_t *pLinkedDevId,
                                           OCStackResult stackresult, bool hasError)
 {
-    OIC_LOG_V(INFO, TAG, "Inside registerResultForRemoveDevice removeData->numOfResults is %zu\n",
+    OIC_LOG_V(INFO, TAG, "Inside registerResultForRemoveDevice removeData->numOfResults is %" PRIuPTR,
                          removeData->numOfResults + 1);
     if (pLinkedDevId)
     {
@@ -1519,7 +2311,7 @@ static void registerResultForRemoveDevice(RemoveData_t *removeData, OicUuid_t *p
 static void registerResultForResetDevice(RemoveData_t *removeData, OicUuid_t *pLinkedDevId,
                                           OCStackResult stackresult, bool hasError)
 {
-    OIC_LOG_V(INFO, TAG, "Inside registerResultForResetDevice removeData->numOfResults is %zu\n",
+    OIC_LOG_V(INFO, TAG, "Inside registerResultForResetDevice removeData->numOfResults is %" PRIuPTR,
                          removeData->numOfResults + 1);
     if (pLinkedDevId)
     {
@@ -1560,7 +2352,7 @@ static OCStackApplicationResult SRPRemoveDeviceCB(void *delDevCtx, OCDoHandle ha
     //Save the deleted status in delDevCtx
     (void)handle;
     OIC_LOG_V(INFO, TAG, "Inside SRPRemoveDeviceCB.");
-    VERIFY_NON_NULL(TAG, delDevCtx, ERROR, OC_STACK_DELETE_TRANSACTION);
+    VERIFY_NOT_NULL_RETURN(TAG, delDevCtx, ERROR, OC_STACK_DELETE_TRANSACTION);
     OCStackResult res = OC_STACK_ERROR;
 
     RemoveData_t* removeData = (RemoveData_t*)delDevCtx;
@@ -1619,7 +2411,6 @@ static OCStackApplicationResult SRPRemoveDeviceCB(void *delDevCtx, OCDoHandle ha
         OIC_LOG(ERROR, TAG, "SRPRemoveDevices received Null clientResponse");
     }
 
-
     return OC_STACK_DELETE_TRANSACTION;
 }
 
@@ -1639,7 +2430,7 @@ static OCStackApplicationResult SRPSyncDeviceCredCB(void *delDevCtx, OCDoHandle
     //Save the deleted status in delDevCtx
     (void)handle;
     OIC_LOG_V(INFO, TAG, "Inside SRPSyncDeviceCredCB.");
-    VERIFY_NON_NULL(TAG, delDevCtx, ERROR, OC_STACK_DELETE_TRANSACTION);
+    VERIFY_NOT_NULL_RETURN(TAG, delDevCtx, ERROR, OC_STACK_DELETE_TRANSACTION);
     OCStackResult res = OC_STACK_ERROR;
 
     RemoveData_t* removeData = (RemoveData_t*)delDevCtx;
@@ -1713,9 +2504,12 @@ static OCStackApplicationResult SRPSyncDeviceCredCB(void *delDevCtx, OCDoHandle
  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
  */
-static OCStackApplicationResult SRPSyncDeviceACLCB(void *ctx, OCDoHandle handle,
+static OCStackApplicationResult SRPSyncDeviceACLCB(void *ctx, OCDoHandle UNUSED,
         OCClientResponse *clientResponse)
 {
+    (void)ctx;
+    (void)UNUSED;
+    (void)clientResponse;
     return OC_STACK_DELETE_TRANSACTION;
 }
 
@@ -1723,15 +2517,16 @@ static OCStackApplicationResult SRPSyncDeviceACLCB(void *ctx, OCDoHandle handle,
  * Callback handler of device remote reset.
  *
  * @param[in] ctx             ctx value passed to callback from calling function.
- * @param[in] handle          handle to an invocation
+ * @param[in] UNUSED          handle to an invocation
  * @param[in] clientResponse  Response from queries to remote servers.
  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
  */
-static OCStackApplicationResult SRPResetDeviceCB(void *ctx, OCDoHandle handle,
+static OCStackApplicationResult SRPResetDeviceCB(void *ctx, OCDoHandle UNUSED,
         OCClientResponse *clientResponse)
 {
     OIC_LOG(DEBUG, TAG, "IN SRPResetDeviceCB");
+    (void)UNUSED;
     if(OC_STACK_OK == clientResponse->result)
     {
         OIC_LOG(DEBUG, TAG, "Change Target Device Pstat Cm SUCCEEDED");
@@ -1767,7 +2562,7 @@ static OCStackApplicationResult SRPResetDeviceCB(void *ctx, OCDoHandle handle,
 
     //Close the DTLS session of the reset device.
     CAEndpoint_t* endpoint = (CAEndpoint_t *)&clientResponse->devAddr;
-    CAResult_t caResult = CACloseDtlsSession(endpoint);
+    CAResult_t caResult = CAcloseSslSession(endpoint);
     if(CA_STATUS_OK != caResult)
     {
         OIC_LOG_V(WARNING, TAG, "OCResetDevice : Failed to close DTLS session : %d", caResult);
@@ -1789,7 +2584,7 @@ error:
 }
 
 static OCStackResult GetListofDevToReqDeleteCred(const OCProvisionDev_t* pRevokeTargetDev,
-                                                 OCProvisionDev_t* pOwnedDevList,
+                                                 const OCProvisionDev_t* pOwnedDevList,
                                                  OCUuidList_t* pLinkedUuidList,
                                                  OCProvisionDev_t** ppLinkedDevList,
                                                  size_t *numOfLinkedDev)
@@ -1816,7 +2611,8 @@ static OCStackResult GetListofDevToReqDeleteCred(const OCProvisionDev_t* pRevoke
         if (pOwnedDevList)
         {
             // If this linked device is alive (power-on), add the deivce to the list.
-            OCProvisionDev_t *curDev = NULL, *tmpDev = NULL;
+            const OCProvisionDev_t *curDev = NULL;
+            const OCProvisionDev_t *tmpDev = NULL;
             LL_FOREACH_SAFE(pOwnedDevList, curDev, tmpDev)
             {
                 if (memcmp(curDev->doxm->deviceID.id, curUuid->dev.id, sizeof(curUuid->dev.id)) == 0)
@@ -1920,7 +2716,7 @@ OCStackResult SRPRemoveDevice(void* ctx, unsigned short waitTimeForOwnedDeviceDi
     removeData = (RemoveData_t*)OICCalloc(1, sizeof(RemoveData_t));
     if (!removeData)
     {
-        OIC_LOG(ERROR, TAG, "SRPRemoveDevices : Failed to memory allocation");
+        OIC_LOG(ERROR, TAG, "SRPRemoveDevices : Failed to allocate memory");
         res = OC_STACK_NO_MEMORY;
         goto error;
     }
@@ -1937,7 +2733,7 @@ OCStackResult SRPRemoveDevice(void* ctx, unsigned short waitTimeForOwnedDeviceDi
         (OCProvisionResult_t*)OICCalloc(numOfLinkedDev, sizeof(OCProvisionResult_t));
     if (!removeData->removeRes)
     {
-        OIC_LOG(ERROR, TAG, "SRPRemoveDevices : Failed to memory allocation");
+        OIC_LOG(ERROR, TAG, "SRPRemoveDevices : Failed to allocate memory");
         res = OC_STACK_NO_MEMORY;
         goto error;
     }
@@ -2005,7 +2801,12 @@ OCStackResult SRPRemoveDeviceWithoutDiscovery(void* ctx, const OCProvisionDev_t*
 {
     OIC_LOG(INFO, TAG, "IN SRPRemoveDeviceWithoutDiscovery");
 
-    if (!pTargetDev  || !pOwnedDevList)
+    if (!pOwnedDevList)
+    {
+        OIC_LOG(WARNING, TAG, "SRPRemoveDeviceWithoutDiscovery : Owned Device List is empty");
+        return OC_STACK_CONTINUE;
+    }
+    if (!pTargetDev)
     {
         OIC_LOG(INFO, TAG, "SRPRemoveDeviceWithoutDiscovery : NULL parameters");
         return OC_STACK_INVALID_PARAM;
@@ -2027,15 +2828,14 @@ OCStackResult SRPRemoveDeviceWithoutDiscovery(void* ctx, const OCProvisionDev_t*
     res = PDMGetLinkedDevices(&pTargetDev->doxm->deviceID, &pLinkedUuidList, &numOfDevices);
     if (OC_STACK_OK != res)
     {
-        OIC_LOG(ERROR, TAG, "SRPRemoveDeviceWithoutDiscovery : Failed to get linked devices information");
-        return res;
+        OIC_LOG(WARNING, TAG, "SRPRemoveDeviceWithoutDiscovery : Failed to get linked devices information");
+        return OC_STACK_CONTINUE;
     }
     // if there is no related device, we can skip further process.
     if (0 == numOfDevices)
     {
-        OIC_LOG(DEBUG, TAG, "SRPRemoveDeviceWithoutDiscovery : No linked device found.");
-        res = OC_STACK_CONTINUE;
-        goto error;
+        OIC_LOG(WARNING, TAG, "SRPRemoveDeviceWithoutDiscovery : No linked device found.");
+        return OC_STACK_CONTINUE;
     }
 
     //2. Make a list of devices to send DELETE credential request
@@ -2051,15 +2851,14 @@ OCStackResult SRPRemoveDeviceWithoutDiscovery(void* ctx, const OCProvisionDev_t*
     if (0 == numOfLinkedDev) // This case means, there is linked device but it's not alive now.
     {                       // So we don't have to send request message.
         OIC_LOG(DEBUG, TAG, "SRPRemoveDeviceWithoutDiscovery : No alived & linked device found.");
-        res = OC_STACK_CONTINUE;
-        goto error;
+        return OC_STACK_CONTINUE;
     }
 
     // 3. Prepare RemoveData Context data.
     removeData = (RemoveData_t*)OICCalloc(1, sizeof(RemoveData_t));
     if (!removeData)
     {
-        OIC_LOG(ERROR, TAG, "SRPRemoveDeviceWithoutDiscovery : Failed to memory allocation");
+        OIC_LOG(ERROR, TAG, "SRPRemoveDeviceWithoutDiscovery : Failed to allocate memory");
         res = OC_STACK_NO_MEMORY;
         goto error;
     }
@@ -2076,7 +2875,7 @@ OCStackResult SRPRemoveDeviceWithoutDiscovery(void* ctx, const OCProvisionDev_t*
         (OCProvisionResult_t*)OICCalloc(numOfLinkedDev, sizeof(OCProvisionResult_t));
     if (!removeData->removeRes)
     {
-        OIC_LOG(ERROR, TAG, "SRPRemoveDeviceWithoutDiscovery : Failed to memory allocation");
+        OIC_LOG(ERROR, TAG, "SRPRemoveDeviceWithoutDiscovery : Failed to allocate memory");
         res = OC_STACK_NO_MEMORY;
         goto error;
     }
@@ -2205,7 +3004,7 @@ OCStackResult SRPSyncDevice(void* ctx, unsigned short waitTimeForOwnedDeviceDisc
     removeData = (RemoveData_t*)OICCalloc(1, sizeof(RemoveData_t));
     if (!removeData)
     {
-        OIC_LOG(ERROR, TAG, "SRPSyncDevice : Failed to memory allocation");
+        OIC_LOG(ERROR, TAG, "SRPSyncDevice : Failed to allocate memory");
         res = OC_STACK_NO_MEMORY;
         goto error;
     }
@@ -2316,11 +3115,12 @@ OCStackResult SRPResetDevice(const OCProvisionDev_t* pTargetDev,
         return OC_STACK_NO_MEMORY;
     }
 
+    pstat->dos.state = DOS_RESET; // TODO IOT-2052 in OCF 1.0 this is the only
+                                  // value that needs to be set to cause RESET
     pstat->cm = RESET;
     pstat->isOp = false;
-    memcpy(pstat->deviceID.id, pTargetDev->doxm->deviceID.id, sizeof(OicUuid_t));
     pstat->tm = TAKE_OWNER;
-    pstat->om = (OicSecDpom_t)(SINGLE_SERVICE_SERVER_DRIVEN | MULTIPLE_SERVICE_CLIENT_DRIVEN);
+    pstat->om = (OicSecDpom_t)(SINGLE_SERVICE_CLIENT_DRIVEN); // the only mode IoTivity supports currently
     pstat->smLen = 1;
     pstat->sm = (OicSecDpom_t *) OICCalloc(pstat->smLen, sizeof(OicSecDpom_t));
     if (NULL == pstat->sm)
@@ -2329,7 +3129,7 @@ OCStackResult SRPResetDevice(const OCProvisionDev_t* pTargetDev,
         OICFree(pstat);
         return OC_STACK_NO_MEMORY;
     }
-    pstat->sm[0] = (OicSecDpom_t)(SINGLE_SERVICE_SERVER_DRIVEN | MULTIPLE_SERVICE_CLIENT_DRIVEN);
+    pstat->sm[0] = (OicSecDpom_t)(SINGLE_SERVICE_CLIENT_DRIVEN); // the only mode IoTivity supports currently
 
     OCSecurityPayload * secPayload = (OCSecurityPayload *) OICCalloc(1, sizeof(OCSecurityPayload));
     if (!secPayload)
@@ -2340,8 +3140,16 @@ OCStackResult SRPResetDevice(const OCProvisionDev_t* pTargetDev,
     }
     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
 
-    if (OC_STACK_OK != PstatToCBORPayload(pstat, &(secPayload->securityData),
-                &(secPayload->payloadSize), true))
+    // Note [IOT-2052] all the POST payloads in the provisioningclient app
+    // should be updated to use the Partial payload APIs for the SVRs, so they
+    // do not include read-only Properties for the Server device current
+    // state.
+    bool propertiesToInclude[PSTAT_PROPERTY_COUNT];
+    memset(propertiesToInclude, 0, sizeof(propertiesToInclude));
+    propertiesToInclude[PSTAT_DOS] = true;
+
+    if (OC_STACK_OK != PstatToCBORPayloadPartial(pstat, &(secPayload->securityData),
+                &(secPayload->payloadSize), propertiesToInclude))
     {
         OCPayloadDestroy((OCPayload *) secPayload);
         OIC_LOG(ERROR, TAG, "Failed to PstatToCBORPayload");
@@ -2365,13 +3173,19 @@ OCStackResult SRPResetDevice(const OCProvisionDev_t* pTargetDev,
     }
     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
 
-    OCProvisionDev_t * targetDev = PMCloneOCProvisionDev(pTargetDev);
     OCCallbackData cbData = { .context = NULL, .cb = NULL, .cd = NULL };
+    OCMethod method = OC_REST_POST;
+    OCDoHandle handle = NULL;
+    OCProvisionDev_t * targetDev = PMCloneOCProvisionDev(pTargetDev);
+    if (NULL == targetDev)
+    {
+        OIC_LOG(ERROR, TAG, "target dev is null");
+        res = OC_STACK_ERROR;
+        goto error;
+    }
     cbData.cb = &SRPResetDeviceCB;
     cbData.context = (void *) targetDev;
     cbData.cd = NULL;
-    OCMethod method = OC_REST_POST;
-    OCDoHandle handle = NULL;
     OIC_LOG(DEBUG, TAG, "Sending PSTAT info to resource server");
     res = OCDoResource(&handle, method, query,
             &targetDev->endpoint, (OCPayload *)secPayload,
@@ -2395,7 +3209,129 @@ static void registerResultForGetCredResourceCB(GetSecData_t *GetSecData,
                                              OCStackResult stackresult)
 {
    OIC_LOG_V(INFO, TAG, "Inside registerResultForGetCredResourceCB "
-           "GetSecData->numOfResults is %d\n", GetSecData->numOfResults);
+           "GetSecData->numOfResults is %d", GetSecData->numOfResults);
+   memcpy(GetSecData->resArr[(GetSecData->numOfResults)].deviceId.id,
+          GetSecData->deviceInfo->doxm->deviceID.id, UUID_LENGTH);
+   GetSecData->resArr[(GetSecData->numOfResults)].res = stackresult;
+   ++(GetSecData->numOfResults);
+}
+
+/**
+ * Callback handler of SRPGetCredResource.
+ *
+ * @param[in] ctx             ctx value passed to callback from calling function.
+ * @param[in] UNUSED          handle to an invocation
+ * @param[in] clientResponse  Response from queries to remote servers.
+ * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
+ *          and  OC_STACK_KEEP_TRANSACTION to keep it.
+ */
+static OCStackApplicationResult SRPGetCredResourceCB(void *ctx, OCDoHandle UNUSED,
+                                                  OCClientResponse *clientResponse)
+{
+    OIC_LOG_V(INFO, TAG, "Inside SRPGetCredResourceCB.");
+    (void)UNUSED;
+    VERIFY_NOT_NULL_RETURN(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
+    GetSecData_t *GetSecData = (GetSecData_t*)ctx;
+    OCProvisionResultCB resultCallback = GetSecData->resultCallback;
+
+    if (clientResponse)
+    {
+        if(OC_STACK_OK == clientResponse->result)
+        {
+            uint8_t *payload = ((OCSecurityPayload*)clientResponse->payload)->securityData;
+            size_t size = ((OCSecurityPayload*)clientResponse->payload)->payloadSize;
+
+            OIC_LOG_BUFFER(DEBUG, TAG, payload, size);
+            (void)size;
+            (void)payload;
+
+            registerResultForGetCredResourceCB(GetSecData, OC_STACK_OK);
+            ((OCProvisionResultCB)(resultCallback))(GetSecData->ctx, GetSecData->numOfResults,
+                                                    GetSecData->resArr,
+                                                    false);
+             OICFree(GetSecData->resArr);
+             OICFree(GetSecData);
+
+            return OC_STACK_DELETE_TRANSACTION;
+        }
+    }
+    registerResultForGetCredResourceCB(GetSecData, OC_STACK_OK);
+    ((OCProvisionResultCB)(resultCallback))(GetSecData->ctx, GetSecData->numOfResults,
+                                            GetSecData->resArr,
+                                            false);
+    OIC_LOG_V(ERROR, TAG, "SRPGetCredResourceCB received Null clientResponse");
+    OICFree(GetSecData->resArr);
+    OICFree(GetSecData);
+
+    return OC_STACK_DELETE_TRANSACTION;
+}
+
+OCStackResult SRPGetCredResource(void *ctx, const OCProvisionDev_t *selectedDeviceInfo,
+        OCProvisionResultCB resultCallback)
+{
+    VERIFY_NOT_NULL_RETURN(TAG, selectedDeviceInfo, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NOT_NULL_RETURN(TAG, resultCallback, ERROR,  OC_STACK_INVALID_CALLBACK);
+
+    char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
+    if(!PMGenerateQuery(true,
+                        selectedDeviceInfo->endpoint.addr,
+                        selectedDeviceInfo->securePort,
+                        selectedDeviceInfo->connType,
+                        query, sizeof(query), OIC_RSRC_CRED_URI))
+    {
+        OIC_LOG(ERROR, TAG, "SRPGetCredResource : Failed to generate query");
+        return OC_STACK_ERROR;
+    }
+    OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
+
+    OCCallbackData cbData =  {.context=NULL, .cb=NULL, .cd=NULL};
+    cbData.cb = &SRPGetCredResourceCB;
+    GetSecData_t* GetSecData = (GetSecData_t*)OICCalloc(1, sizeof(GetSecData_t));
+    if (NULL == GetSecData)
+    {
+        OIC_LOG(ERROR, TAG, "Unable to allocate memory");
+        return OC_STACK_NO_MEMORY;
+    }
+    GetSecData->deviceInfo = selectedDeviceInfo;
+    GetSecData->resultCallback = resultCallback;
+    GetSecData->numOfResults=0;
+    GetSecData->ctx = ctx;
+
+    int noOfRiCalls = 1;
+    GetSecData->resArr = (OCProvisionResult_t*)OICCalloc(noOfRiCalls, sizeof(OCProvisionResult_t));
+    if (NULL == GetSecData->resArr)
+    {
+        OICFree(GetSecData);
+        OIC_LOG(ERROR, TAG, "Unable to allocate memory");
+        return OC_STACK_NO_MEMORY;
+    }
+    cbData.context = (void *)GetSecData;
+    cbData.cd = NULL;
+    OCMethod method = OC_REST_GET;
+    OCDoHandle handle = NULL;
+    OIC_LOG(DEBUG, TAG, "Sending Get Cred to  resource server");
+    OCStackResult ret = OCDoResource(&handle, method, query, NULL, NULL,
+            selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
+    if (OC_STACK_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "OCStack resource error");
+        OICFree(GetSecData->resArr);
+        OICFree(GetSecData);
+    }
+    VERIFY_SUCCESS_RETURN(TAG, (OC_STACK_OK == ret), ERROR, OC_STACK_ERROR);
+    OIC_LOG(DEBUG, TAG, "OUT SRPGetCredResource");
+
+    return OC_STACK_OK;
+}
+
+/**
+ * Internal Function to store results in result array during GetACLResourceCB.
+ */
+static void registerResultForGetACLResourceCB(GetSecData_t *GetSecData,
+                                             OCStackResult stackresult)
+{
+   OIC_LOG_V(INFO, TAG, "Inside registerResultForGetACLResourceCB "
+           "GetSecData->numOfResults is %d", GetSecData->numOfResults);
    memcpy(GetSecData->resArr[(GetSecData->numOfResults)].deviceId.id,
           GetSecData->deviceInfo->doxm->deviceID.id, UUID_LENGTH);
    GetSecData->resArr[(GetSecData->numOfResults)].res = stackresult;
@@ -2403,7 +3339,168 @@ static void registerResultForGetCredResourceCB(GetSecData_t *GetSecData,
 }
 
 /**
- * Callback handler of SRPGetCredResource.
+ * Callback handler of SRPGetACLResource.
+ *
+ * @param[in] ctx             ctx value passed to callback from calling function.
+ * @param[in] UNUSED          handle to an invocation
+ * @param[in] clientResponse  Response from queries to remote servers.
+ * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
+ *          and  OC_STACK_KEEP_TRANSACTION to keep it.
+ */
+static OCStackApplicationResult SRPGetACLResourceCB(void *ctx, OCDoHandle UNUSED,
+                                                  OCClientResponse *clientResponse)
+{
+    OIC_LOG_V(INFO, TAG, "Inside SRPGetACLResourceCB.");
+    (void)UNUSED;
+    VERIFY_NOT_NULL_RETURN(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
+    GetSecData_t *GetSecData = (GetSecData_t*)ctx;
+    OCProvisionResultCB resultCallback = GetSecData->resultCallback;
+
+    if (clientResponse)
+    {
+        if(OC_STACK_OK == clientResponse->result)
+        {
+            uint8_t *payload = ((OCSecurityPayload*)clientResponse->payload)->securityData;
+            size_t size = ((OCSecurityPayload*)clientResponse->payload)->payloadSize;
+
+            OIC_LOG_BUFFER(DEBUG, TAG, payload, size);
+            (void)payload;
+            (void)size;
+
+            registerResultForGetACLResourceCB(GetSecData, OC_STACK_OK);
+            ((OCProvisionResultCB)(resultCallback))(GetSecData->ctx, GetSecData->numOfResults,
+                                                    GetSecData->resArr,
+                                                    false);
+             OICFree(GetSecData->resArr);
+             OICFree(GetSecData);
+
+            return OC_STACK_DELETE_TRANSACTION;
+        }
+    }
+    registerResultForGetACLResourceCB(GetSecData, OC_STACK_OK);
+    ((OCProvisionResultCB)(resultCallback))(GetSecData->ctx, GetSecData->numOfResults,
+                                            GetSecData->resArr,
+                                            false);
+    OIC_LOG_V(ERROR, TAG, "SRPGetACLResourceCB received Null clientResponse");
+    OICFree(GetSecData->resArr);
+    OICFree(GetSecData);
+
+    return OC_STACK_DELETE_TRANSACTION;
+}
+
+OCStackResult SRPGetACLResource(void *ctx, const OCProvisionDev_t *selectedDeviceInfo,
+        OicSecAclVersion_t aclVersion, OCProvisionResultCB resultCallback)
+{
+    VERIFY_NOT_NULL_RETURN(TAG, selectedDeviceInfo, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NOT_NULL_RETURN(TAG, resultCallback, ERROR,  OC_STACK_INVALID_CALLBACK);
+
+    const char *uri = NULL;
+
+    switch (aclVersion)
+    {
+    case OIC_SEC_ACL_V1:
+        OIC_LOG_V(WARNING, TAG, "%s using ACL v1... this should only be used for provisioning OIC 1.1 and earlier Servers.", __func__);
+        uri = OIC_RSRC_ACL_URI;
+        break;
+    case OIC_SEC_ACL_V2:
+        uri = OIC_RSRC_ACL2_URI;
+        break;
+    default:
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
+    if(!PMGenerateQuery(true,
+                        selectedDeviceInfo->endpoint.addr,
+                        selectedDeviceInfo->securePort,
+                        selectedDeviceInfo->connType,
+                        query, sizeof(query), uri))
+    {
+        OIC_LOG(ERROR, TAG, "SRPGetACLResource : Failed to generate query");
+        return OC_STACK_ERROR;
+    }
+    OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
+
+    OCCallbackData cbData =  {.context=NULL, .cb=NULL, .cd=NULL};
+    cbData.cb = &SRPGetACLResourceCB;
+    GetSecData_t* GetSecData = (GetSecData_t*)OICCalloc(1, sizeof(GetSecData_t));
+    if (NULL == GetSecData)
+    {
+        OIC_LOG(ERROR, TAG, "Unable to allocate memory");
+        return OC_STACK_NO_MEMORY;
+    }
+    GetSecData->deviceInfo = selectedDeviceInfo;
+    GetSecData->resultCallback = resultCallback;
+    GetSecData->numOfResults=0;
+    GetSecData->ctx = ctx;
+
+    int noOfRiCalls = 1;
+    GetSecData->resArr = (OCProvisionResult_t*)OICCalloc(noOfRiCalls, sizeof(OCProvisionResult_t));
+    if (NULL == GetSecData->resArr)
+    {
+        OICFree(GetSecData);
+        OIC_LOG(ERROR, TAG, "Unable to allocate memory");
+        return OC_STACK_NO_MEMORY;
+    }
+    cbData.context = (void *)GetSecData;
+    cbData.cd = NULL;
+    OCMethod method = OC_REST_GET;
+    OCDoHandle handle = NULL;
+    OIC_LOG(DEBUG, TAG, "Sending Get ACL to resource server");
+    OCStackResult ret = OCDoResource(&handle, method, query, NULL, NULL,
+            selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
+    if (OC_STACK_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "OCStack resource error");
+        OICFree(GetSecData->resArr);
+        OICFree(GetSecData);
+    }
+    VERIFY_SUCCESS_RETURN(TAG, (OC_STACK_OK == ret), ERROR, OC_STACK_ERROR);
+    OIC_LOG(DEBUG, TAG, "OUT SRPGetACLResource");
+
+    return OC_STACK_OK;
+}
+
+/**
+ * Internal Function to store results in result array during GetCSRResourceCB.
+ */
+static void registerResultForGetCSRResourceCB(GetCsrData_t *getCsrData,
+                                             OCStackResult stackresult,
+                                             const uint8_t *payload,
+                                             size_t payloadSize)
+{
+    /* SRPGetCSRResource allocates the memory for getCsrData. When it calls this callback,
+     * numOfResults points to the current entry we're filling out. Later when this structure
+     * gets returned to the caller, that's when it actually reflects the number of
+     * results returned.
+     */
+    OCPMGetCsrResult_t* currentEntry = &getCsrData->resArr[getCsrData->numOfResults];
+    OIC_LOG_V(INFO, TAG, "Inside registerResultForGetCSRResourceCB "
+        "getCsrData->numOfResults is %zu\n", getCsrData->numOfResults);
+    memcpy(currentEntry->deviceId.id,
+        getCsrData->deviceInfo->doxm->deviceID.id, UUID_LENGTH);
+    currentEntry->res = stackresult;
+
+    if (OC_STACK_OK == stackresult)
+    {
+        OCStackResult res = CBORPayloadToCSR(payload, payloadSize,
+            &currentEntry->csr,
+            &currentEntry->csrLen,
+            &currentEntry->encoding);
+        if (OC_STACK_OK != res)
+        {
+            currentEntry->res = res;
+            currentEntry->csr = NULL;
+            currentEntry->csrLen = 0;
+            currentEntry->encoding = OIC_ENCODING_UNKNOW;
+        }
+    }
+
+    ++(getCsrData->numOfResults);
+}
+
+/**
+ * Callback handler of SRPGetCSRResource.
  *
  * @param[in] ctx             ctx value passed to callback from calling function.
  * @param[in] UNUSED          handle to an invocation
@@ -2411,120 +3508,173 @@ static void registerResultForGetCredResourceCB(GetSecData_t *GetSecData,
  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
  */
-static OCStackApplicationResult SRPGetCredResourceCB(void *ctx, OCDoHandle UNUSED,
-                                                  OCClientResponse *clientResponse)
+static OCStackApplicationResult SRPGetCSRResourceCB(void *ctx, OCDoHandle UNUSED,
+    OCClientResponse *clientResponse)
 {
-    OIC_LOG_V(INFO, TAG, "Inside SRPGetCredResourceCB.");
-    (void)UNUSED;
-    VERIFY_NON_NULL(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
-    GetSecData_t *GetSecData = (GetSecData_t*)ctx;
-    OCProvisionResultCB resultCallback = GetSecData->resultCallback;
+    size_t i = 0;
+    OIC_LOG_V(INFO, TAG, "IN %s", __func__);
+    OC_UNUSED(UNUSED);
+    VERIFY_NOT_NULL_RETURN(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
+    GetCsrData_t *getCsrData = (GetCsrData_t*)ctx;
+    OCGetCSRResultCB resultCallback = getCsrData->resultCallback;
 
     if (clientResponse)
     {
-        if(OC_STACK_OK == clientResponse->result)
+        if (OC_STACK_OK == clientResponse->result)
         {
             uint8_t *payload = ((OCSecurityPayload*)clientResponse->payload)->securityData;
             size_t size = ((OCSecurityPayload*)clientResponse->payload)->payloadSize;
 
             OIC_LOG_BUFFER(DEBUG, TAG, payload, size);
 
-            registerResultForGetCredResourceCB(GetSecData, OC_STACK_OK);
-            ((OCProvisionResultCB)(resultCallback))(GetSecData->ctx, GetSecData->numOfResults,
-                                                    GetSecData->resArr,
-                                                    false);
-             OICFree(GetSecData->resArr);
-             OICFree(GetSecData);
-
-            return OC_STACK_DELETE_TRANSACTION;
+            registerResultForGetCSRResourceCB(getCsrData, OC_STACK_OK, payload, size);
         }
     }
-    registerResultForGetCredResourceCB(GetSecData, OC_STACK_OK);
-    ((OCProvisionResultCB)(resultCallback))(GetSecData->ctx, GetSecData->numOfResults,
-                                            GetSecData->resArr,
-                                            false);
-    OIC_LOG_V(ERROR, TAG, "SRPGetCredResourceCB received Null clientResponse");
-    OICFree(GetSecData->resArr);
-    OICFree(GetSecData);
+    else
+    {
+        registerResultForGetCSRResourceCB(getCsrData, OC_STACK_ERROR, NULL, 0);
+    }
+
+    ((OCGetCSRResultCB)(resultCallback))(getCsrData->ctx, getCsrData->numOfResults,
+        getCsrData->resArr,
+        false);
+    OIC_LOG_V(ERROR, TAG, "%s: received Null clientResponse", __func__);
+    for (i = 0; i < getCsrData->numOfResults; i++)
+    {
+        OICFree(getCsrData->resArr[i].csr);
+    }
+    OICFree(getCsrData->resArr);
+    OICFree(getCsrData);
+    OIC_LOG_V(INFO, TAG, "OUT %s", __func__);
 
     return OC_STACK_DELETE_TRANSACTION;
 }
 
-
-OCStackResult SRPGetCredResource(void *ctx, const OCProvisionDev_t *selectedDeviceInfo,
-        OCProvisionResultCB resultCallback)
+OCStackResult SRPGetCSRResource(void *ctx, const OCProvisionDev_t *selectedDeviceInfo,
+        OCGetCSRResultCB resultCallback)
 {
-    VERIFY_NON_NULL(TAG, selectedDeviceInfo, ERROR,  OC_STACK_INVALID_PARAM);
-    VERIFY_NON_NULL(TAG, resultCallback, ERROR,  OC_STACK_INVALID_CALLBACK);
+    VERIFY_NOT_NULL_RETURN(TAG, selectedDeviceInfo, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NOT_NULL_RETURN(TAG, resultCallback, ERROR,  OC_STACK_INVALID_CALLBACK);
 
     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
-    if(!PMGenerateQuery(true,
+    if (!PMGenerateQuery(true,
                         selectedDeviceInfo->endpoint.addr,
                         selectedDeviceInfo->securePort,
                         selectedDeviceInfo->connType,
-                        query, sizeof(query), OIC_RSRC_CRED_URI))
+                        query, sizeof(query), OIC_RSRC_CSR_URI))
     {
-        OIC_LOG(ERROR, TAG, "SRPGetCredResource : Failed to generate query");
+        OIC_LOG(ERROR, TAG, "SRPGetCSRResource : Failed to generate query");
         return OC_STACK_ERROR;
     }
     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
 
     OCCallbackData cbData =  {.context=NULL, .cb=NULL, .cd=NULL};
-    cbData.cb = &SRPGetCredResourceCB;
-    GetSecData_t* GetSecData = (GetSecData_t*)OICCalloc(1, sizeof(GetSecData_t));
-    if (NULL == GetSecData)
+    cbData.cb = &SRPGetCSRResourceCB;
+    GetCsrData_t* getCsrData = (GetCsrData_t*)OICCalloc(1, sizeof(GetCsrData_t));
+    if (NULL == getCsrData)
     {
         OIC_LOG(ERROR, TAG, "Unable to allocate memory");
         return OC_STACK_NO_MEMORY;
     }
-    GetSecData->deviceInfo = selectedDeviceInfo;
-    GetSecData->resultCallback = resultCallback;
-    GetSecData->numOfResults=0;
-    GetSecData->ctx = ctx;
+    getCsrData->deviceInfo = selectedDeviceInfo;
+    getCsrData->resultCallback = resultCallback;
+    getCsrData->numOfResults=0;
+    getCsrData->ctx = ctx;
 
     int noOfRiCalls = 1;
-    GetSecData->resArr = (OCProvisionResult_t*)OICCalloc(noOfRiCalls, sizeof(OCProvisionResult_t));
-    if (NULL == GetSecData->resArr)
+    getCsrData->resArr = (OCPMGetCsrResult_t*)OICCalloc(noOfRiCalls, sizeof(OCPMGetCsrResult_t));
+    if (NULL == getCsrData->resArr)
     {
-        OICFree(GetSecData);
+        OICFree(getCsrData);
         OIC_LOG(ERROR, TAG, "Unable to allocate memory");
         return OC_STACK_NO_MEMORY;
     }
-    cbData.context = (void *)GetSecData;
-    cbData.cd = NULL;
+    cbData.context = (void *)getCsrData;
     OCMethod method = OC_REST_GET;
     OCDoHandle handle = NULL;
-    OIC_LOG(DEBUG, TAG, "Sending Get Cred to  resource server");
+    OIC_LOG(DEBUG, TAG, "Sending Get CSR to resource server");
     OCStackResult ret = OCDoResource(&handle, method, query, NULL, NULL,
             selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
     if (OC_STACK_OK != ret)
     {
         OIC_LOG(ERROR, TAG, "OCStack resource error");
-        OICFree(GetSecData->resArr);
-        OICFree(GetSecData);
+        OICFree(getCsrData->resArr);
+        OICFree(getCsrData);
     }
-    VERIFY_SUCCESS(TAG, (OC_STACK_OK == ret), ERROR, OC_STACK_ERROR);
-    OIC_LOG(DEBUG, TAG, "OUT SRPGetCredResource");
+    OIC_LOG(DEBUG, TAG, "OUT SRPGetCSRResource");
 
-    return OC_STACK_OK;
+    return ret;
 }
 
 /**
- * Internal Function to store results in result array during GetACLResourceCB.
+ * Internal Function to store results in result array during GetRolesResourceCB.
  */
-static void registerResultForGetACLResourceCB(GetSecData_t *GetSecData,
-                                             OCStackResult stackresult)
+static void registerResultForGetRolesResourceCB(GetRolesData_t *getRolesData,
+                                                OCStackResult stackresult,
+                                                const uint8_t *payload,
+                                                size_t payloadSize)
 {
-   OIC_LOG_V(INFO, TAG, "Inside registerResultForGetACLResourceCB "
-           "GetSecData->numOfResults is %d\n", GetSecData->numOfResults);
-   memcpy(GetSecData->resArr[(GetSecData->numOfResults)].deviceId.id,
-          GetSecData->deviceInfo->doxm->deviceID.id, UUID_LENGTH);
-   GetSecData->resArr[(GetSecData->numOfResults)].res = stackresult;
-   ++(GetSecData->numOfResults);
+    /* SRPGetRolesResource allocates the memory for getRolesData. When it calls this callback,
+     * numOfResults points to the current entry we're filling out. Later when this structure
+     * gets returned to the caller, that's when it actually reflects the number of
+     * results returned.
+     */
+    OCPMGetRolesResult_t* currentEntry = &getRolesData->resArr[getRolesData->numOfResults];
+    OIC_LOG_V(INFO, TAG, "Inside registerResultForGetCSRResourceCB "
+        "getRolesData->numOfResults is %zu\n", getRolesData->numOfResults);
+    memcpy(currentEntry->deviceId.id,
+        getRolesData->deviceInfo->doxm->deviceID.id, UUID_LENGTH);
+    currentEntry->res = stackresult;
+    currentEntry->chainsLength = 0;
+
+    if (OC_STACK_OK == stackresult)
+    {
+        RoleCertChain_t *chains = NULL;
+        OCStackResult res = CBORPayloadToRoles(payload, payloadSize, &chains);
+        if (OC_STACK_OK != res)
+        {
+            currentEntry->res = res;
+            currentEntry->chains = NULL;
+        }
+        else
+        {
+            RoleCertChain_t *curr = NULL;
+            for (curr = chains; NULL != curr; curr = curr->next)
+            {
+                currentEntry->chainsLength++;
+            }
+            currentEntry->chains = (OCPMRoleCertChain_t *)OICCalloc(currentEntry->chainsLength, sizeof(OCPMRoleCertChain_t));
+            if (NULL == currentEntry->chains)
+            {
+                OIC_LOG(ERROR, TAG, "No memory allocating role chains");
+                currentEntry->chainsLength = 0;
+                currentEntry->res = OC_STACK_NO_MEMORY;
+            }
+            else
+            {
+                size_t i;
+                for (i = 0, curr = chains; NULL != curr; curr = curr->next, i++)
+                {
+                    currentEntry->chains[i].credId = curr->credId;
+                    /* Take ownership of the buffers from certificate and optData, rather than copy. */
+                    currentEntry->chains[i].certificate = curr->certificate;
+                    currentEntry->chains[i].optData = curr->optData;
+
+                    curr->certificate.data = NULL;
+                    curr->certificate.len = 0;
+                    curr->optData.data = NULL;
+                    curr->optData.len = 0;
+                }
+            }
+            FreeRoleCertChainList(chains);
+        }
+    }
+
+    ++(getRolesData->numOfResults);
 }
 
 /**
- * Callback handler of SRPGetACLResource.
+ * Callback handler of SRPGetRolesResource.
  *
  * @param[in] ctx             ctx value passed to callback from calling function.
  * @param[in] UNUSED          handle to an invocation
@@ -2532,100 +3682,353 @@ static void registerResultForGetACLResourceCB(GetSecData_t *GetSecData,
  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
  */
-static OCStackApplicationResult SRPGetACLResourceCB(void *ctx, OCDoHandle UNUSED,
-                                                  OCClientResponse *clientResponse)
+static OCStackApplicationResult SRPGetRolesResourceCB(void *ctx, OCDoHandle handle,
+                                                      OCClientResponse *clientResponse)
 {
-    OIC_LOG_V(INFO, TAG, "Inside SRPGetACLResourceCB.");
-    (void)UNUSED;
-    VERIFY_NON_NULL(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
-    GetSecData_t *GetSecData = (GetSecData_t*)ctx;
-    OCProvisionResultCB resultCallback = GetSecData->resultCallback;
+    OIC_LOG(INFO, TAG, "Inside SRPGetRolesResourceCB.");
+    OC_UNUSED(handle);
+    VERIFY_NOT_NULL_RETURN(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
+    GetRolesData_t *getRolesData = (GetRolesData_t*)ctx;
+    OCGetRolesResultCB resultCallback = getRolesData->resultCallback;
 
     if (clientResponse)
     {
-        if(OC_STACK_OK == clientResponse->result)
+        if (OC_STACK_OK == clientResponse->result)
         {
             uint8_t *payload = ((OCSecurityPayload*)clientResponse->payload)->securityData;
             size_t size = ((OCSecurityPayload*)clientResponse->payload)->payloadSize;
 
             OIC_LOG_BUFFER(DEBUG, TAG, payload, size);
 
-            registerResultForGetACLResourceCB(GetSecData, OC_STACK_OK);
-            ((OCProvisionResultCB)(resultCallback))(GetSecData->ctx, GetSecData->numOfResults,
-                                                    GetSecData->resArr,
-                                                    false);
-             OICFree(GetSecData->resArr);
-             OICFree(GetSecData);
+            registerResultForGetRolesResourceCB(getRolesData, OC_STACK_OK, payload, size);
+        }
+    }
+    else
+    {
+        OIC_LOG(ERROR, TAG, "SRPGetRolesResourceCB received Null clientResponse");
+        registerResultForGetRolesResourceCB(getRolesData, OC_STACK_ERROR, NULL, 0);
+    }
 
-            return OC_STACK_DELETE_TRANSACTION;
+    resultCallback(getRolesData->ctx, getRolesData->numOfResults,
+                   getRolesData->resArr,
+                   false);
+    for (size_t i = 0; i < getRolesData->numOfResults; i++)
+    {
+        /* We took ownership of certificate.data and optData.data, so we must free them.
+         * These are allocated internally by tinycbor, which uses malloc and free, so we call
+         * free directly for those.
+         */
+        for (size_t j = 0; j < getRolesData->resArr[i].chainsLength; j++)
+        {
+            free(getRolesData->resArr[i].chains[j].certificate.data);
+            free(getRolesData->resArr[i].chains[j].optData.data);
         }
+        OICFree(getRolesData->resArr[i].chains);
     }
-    registerResultForGetACLResourceCB(GetSecData, OC_STACK_OK);
-    ((OCProvisionResultCB)(resultCallback))(GetSecData->ctx, GetSecData->numOfResults,
-                                            GetSecData->resArr,
-                                            false);
-    OIC_LOG_V(ERROR, TAG, "SRPGetACLResourceCB received Null clientResponse");
-    OICFree(GetSecData->resArr);
-    OICFree(GetSecData);
+    OICFree(getRolesData->resArr);
+    OICFree(getRolesData);
 
     return OC_STACK_DELETE_TRANSACTION;
 }
 
+OCStackResult SRPGetRolesResource(void *ctx, const OCProvisionDev_t *selectedDeviceInfo,
+        OCGetRolesResultCB resultCallback)
+{
+    VERIFY_NOT_NULL_RETURN(TAG, selectedDeviceInfo, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NOT_NULL_RETURN(TAG, resultCallback, ERROR,  OC_STACK_INVALID_CALLBACK);
 
-OCStackResult SRPGetACLResource(void *ctx, const OCProvisionDev_t *selectedDeviceInfo,
-        OCProvisionResultCB resultCallback)
+    char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
+    if (!PMGenerateQuery(true,
+                        selectedDeviceInfo->endpoint.addr,
+                        selectedDeviceInfo->securePort,
+                        selectedDeviceInfo->connType,
+                        query, sizeof(query), OIC_RSRC_ROLES_URI))
+    {
+        OIC_LOG(ERROR, TAG, "SRPGetRolesResource : Failed to generate query");
+        return OC_STACK_ERROR;
+    }
+    OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
+
+    OCCallbackData cbData =  {.context=NULL, .cb=NULL, .cd=NULL};
+    cbData.cb = &SRPGetRolesResourceCB;
+    GetRolesData_t *getRolesData = (GetRolesData_t*)OICCalloc(1, sizeof(GetRolesData_t));
+    if (NULL == getRolesData)
+    {
+        OIC_LOG(ERROR, TAG, "Unable to allocate memory");
+        return OC_STACK_NO_MEMORY;
+    }
+    getRolesData->deviceInfo = selectedDeviceInfo;
+    getRolesData->resultCallback = resultCallback;
+    getRolesData->numOfResults = 0;
+    getRolesData->ctx = ctx;
+
+    getRolesData->resArr = (OCPMGetRolesResult_t*)OICCalloc(1, sizeof(OCPMGetRolesResult_t));
+    if (NULL == getRolesData->resArr)
+    {
+        OICFree(getRolesData);
+        OIC_LOG(ERROR, TAG, "Unable to allocate memory");
+        return OC_STACK_NO_MEMORY;
+    }
+    cbData.context = (void *)getRolesData;
+    OCDoHandle handle = NULL;
+    OIC_LOG(DEBUG, TAG, "Sending Get Roles to resource server");
+    OCStackResult ret = OCDoResource(&handle, OC_REST_GET, query, NULL, NULL,
+            selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
+    if (OC_STACK_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "OCStack resource error");
+        OICFree(getRolesData->resArr);
+        OICFree(getRolesData);
+    }
+    OIC_LOG(DEBUG, TAG, "OUT SRPGetRolesResource");
+
+    return ret;
+}
+
+/**
+ * Callback handler of SRPDeleteRoleCertificateByCredId.
+ *
+ * @param[in] ctx             ctx value passed to callback from calling function.
+ * @param[in] UNUSED          handle to an invocation
+ * @param[in] clientResponse  Response from queries to remote servers.
+ * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
+ *          and  OC_STACK_KEEP_TRANSACTION to keep it.
+ */
+static OCStackApplicationResult SRPDeleteRoleCertificateCB(void *ctx, OCDoHandle UNUSED,
+                                                           OCClientResponse *clientResponse)
+{
+    OC_UNUSED(UNUSED);
+    GetSecData_t *getSecData = (GetSecData_t *)ctx;
+    OCProvisionResultCB resultCallback = getSecData->resultCallback;
+
+    OIC_LOG(DEBUG, TAG, "SRPDeleteRoleCertificateCB IN");
+
+    if (NULL != clientResponse)
+    {
+        memcpy(getSecData->resArr[(getSecData->numOfResults)].deviceId.id,
+            getSecData->deviceInfo->doxm->deviceID.id, UUID_LENGTH);
+        getSecData->resArr[(getSecData->numOfResults)].res = clientResponse->result;
+        ++(getSecData->numOfResults);
+        resultCallback(getSecData->ctx, getSecData->numOfResults, getSecData->resArr, false);
+    }
+
+    OIC_LOG(DEBUG, TAG, "SRPDeleteRoleCertificateCB OUT");
+
+    return OC_STACK_DELETE_TRANSACTION;
+}
+
+OCStackResult SRPDeleteRoleCertificateByCredId(void* ctx, const OCProvisionDev_t *selectedDeviceInfo,
+                                               OCProvisionResultCB resultCallback, uint32_t credId)
 {
-    VERIFY_NON_NULL(TAG, selectedDeviceInfo, ERROR,  OC_STACK_INVALID_PARAM);
-    VERIFY_NON_NULL(TAG, resultCallback, ERROR,  OC_STACK_INVALID_CALLBACK);
+    VERIFY_NOT_NULL_RETURN(TAG, selectedDeviceInfo, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NOT_NULL_RETURN(TAG, resultCallback, ERROR,  OC_STACK_INVALID_CALLBACK);
 
     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
-    if(!PMGenerateQuery(true,
+    if (!PMGenerateQuery(true,
                         selectedDeviceInfo->endpoint.addr,
                         selectedDeviceInfo->securePort,
                         selectedDeviceInfo->connType,
-                        query, sizeof(query), OIC_RSRC_ACL_URI))
+                        query, sizeof(query), OIC_RSRC_ROLES_URI))
     {
-        OIC_LOG(ERROR, TAG, "SRPGetACLResource : Failed to generate query");
+        OIC_LOG(ERROR, TAG, "SRPDeleteRoleCertificateByCredId : Failed to generate query");
+        return OC_STACK_ERROR;
+    }
+    size_t queryLen = strlen(query);
+    int snRet = snprintf(query + queryLen, sizeof(query) - queryLen, "?credId=%u", credId);
+
+    if (0 > snRet)
+    {
+        OIC_LOG_V(ERROR, TAG, "snprintf returned error: %d", snRet);
+        return OC_STACK_ERROR;
+    }
+    else if ((size_t)snRet >= (sizeof(query) - queryLen))
+    {
+        OIC_LOG_V(ERROR, TAG, "snprintf truncated");
         return OC_STACK_ERROR;
     }
+
     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
 
     OCCallbackData cbData =  {.context=NULL, .cb=NULL, .cd=NULL};
-    cbData.cb = &SRPGetACLResourceCB;
-    GetSecData_t* GetSecData = (GetSecData_t*)OICCalloc(1, sizeof(GetSecData_t));
-    if (NULL == GetSecData)
+    cbData.cb = &SRPDeleteRoleCertificateCB;
+    GetSecData_t *getSecData = (GetSecData_t*)OICCalloc(1, sizeof(GetSecData_t));
+    if (NULL == getSecData)
     {
         OIC_LOG(ERROR, TAG, "Unable to allocate memory");
         return OC_STACK_NO_MEMORY;
     }
-    GetSecData->deviceInfo = selectedDeviceInfo;
-    GetSecData->resultCallback = resultCallback;
-    GetSecData->numOfResults=0;
-    GetSecData->ctx = ctx;
+    getSecData->deviceInfo = selectedDeviceInfo;
+    getSecData->resultCallback = resultCallback;
+    getSecData->numOfResults = 0;
+    getSecData->ctx = ctx;
 
-    int noOfRiCalls = 1;
-    GetSecData->resArr = (OCProvisionResult_t*)OICCalloc(noOfRiCalls, sizeof(OCProvisionResult_t));
-    if (NULL == GetSecData->resArr)
+    getSecData->resArr = (OCProvisionResult_t*)OICCalloc(1, sizeof(OCProvisionResult_t));
+    if (NULL == getSecData->resArr)
     {
-        OICFree(GetSecData);
+        OICFree(getSecData);
         OIC_LOG(ERROR, TAG, "Unable to allocate memory");
         return OC_STACK_NO_MEMORY;
     }
-    cbData.context = (void *)GetSecData;
-    cbData.cd = NULL;
-    OCMethod method = OC_REST_GET;
+    cbData.context = (void *)getSecData;
+    OCMethod method = OC_REST_DELETE;
     OCDoHandle handle = NULL;
-    OIC_LOG(DEBUG, TAG, "Sending Get ACL to resource server");
+    OIC_LOG(DEBUG, TAG, "Sending Delete Roles to resource server");
     OCStackResult ret = OCDoResource(&handle, method, query, NULL, NULL,
             selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
     if (OC_STACK_OK != ret)
     {
         OIC_LOG(ERROR, TAG, "OCStack resource error");
-        OICFree(GetSecData->resArr);
-        OICFree(GetSecData);
+        OICFree(getSecData->resArr);
+        OICFree(getSecData);
     }
-    VERIFY_SUCCESS(TAG, (OC_STACK_OK == ret), ERROR, OC_STACK_ERROR);
-    OIC_LOG(DEBUG, TAG, "OUT SRPGetACLResource");
+    OIC_LOG(DEBUG, TAG, "OUT SRPGetRolesResource");
+
+    return ret;
+}
+
+OCStackResult SRPReadTrustCertChain(uint16_t credId, uint8_t **trustCertChain,
+                                     size_t *chainSize)
+{
+    OIC_LOG(DEBUG, TAG, "IN SRPReadTrustCertChain");
+
+    OCStackResult res = OC_STACK_ERROR;
+    int secureFlag = 0;
+    OicSecCred_t* credData = GetCredEntryByCredId(credId);
+    if(credData)
+    {
+        res = CredToCBORPayload((const OicSecCred_t*) credData, trustCertChain,
+                                chainSize, secureFlag);
+        if(OC_STACK_OK != res)
+        {
+            OIC_LOG(INFO, TAG, "CredToCBORPayload failed");
+        }
+    }
+    DeleteCredList(credData);
+    return res;
+}
+
+
+/**
+ * Updates provisioning result.
+ */
+static void RegisterProvResult(const OCProvisionDev_t *targetDev, OCProvisionResult_t *resArr,
+                               int *numOfResults, OCStackResult stackResult)
+{
+
+    OIC_LOG_V(INFO, TAG, "value of  numOfResults is %d", *numOfResults);
+    memcpy(resArr[*numOfResults].deviceId.id, targetDev->doxm->deviceID.id, UUID_LENGTH);
+    resArr[*numOfResults].res = stackResult;
+    (*numOfResults)++;
+}
+
+static OCStackApplicationResult ProvisionAclCB(void *ctx, OCDoHandle UNUSED,
+        OCClientResponse *clientResponse)
+{
+    if (NULL == ctx || NULL == clientResponse)
+    {
+        OIC_LOG_V(ERROR, TAG, " ctx: %p, clientResponse: %p", ctx, clientResponse);
+        return OC_STACK_INVALID_PARAM;
+    }
+    (void) UNUSED;
+    if (OC_STACK_RESOURCE_CHANGED == clientResponse->result)
+    {
+        Data_t *data = (Data_t *) ctx;
+        if (ACL_TYPE != data->type)
+        {
+            OIC_LOG(ERROR, TAG, "Invalid type");
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        ACLData_t *aclData = (ACLData_t *) (data->ctx);
+
+        const char *uri = NULL;
+
+        switch (aclData->aclVersion)
+        {
+            case OIC_SEC_ACL_V1:
+                OIC_LOG(WARNING, TAG,
+                        "%s using ACL v1... this should only be used for provisioning OIC 1.1 and earlier Servers.");
+                uri = OIC_RSRC_ACL_URI;
+                break;
+            case OIC_SEC_ACL_V2:
+                uri = OIC_RSRC_ACL2_URI;
+                break;
+            default:
+                return OC_STACK_INVALID_PARAM;
+        }
+
+        // if rowneruuid is empty, set it to device ID
+        OicUuid_t emptyOwner = {.id = {0} };
+        if (memcmp(&(aclData->acl->rownerID.id), &emptyOwner, UUID_IDENTITY_SIZE) == 0)
+        {
+            OIC_LOG(DEBUG, TAG, "Set Rowner to PT's deviceId, because Rowner of ACL is empty");
+            OicUuid_t oicUuid;
+
+            if (OC_STACK_OK == GetDoxmDeviceID(&oicUuid))
+            {
+                memcpy(&(aclData->acl->rownerID.id), &oicUuid, UUID_IDENTITY_SIZE);
+            }
+            else
+            {
+                OIC_LOG(ERROR, TAG, "Failed to set Rowner to PT's deviceID\
+                    becuase it failed to retrieve Doxm DeviceID");
+                return OC_STACK_ERROR;
+            }
+        }
 
+        OCSecurityPayload *secPayload = (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
+        if (!secPayload)
+        {
+            OIC_LOG(ERROR, TAG, "Failed to allocate memory");
+            OIC_LOG_V(ERROR, TAG, "OUT %s", __func__);
+            return OC_STACK_NO_MEMORY;
+        }
+        secPayload->base.type = PAYLOAD_TYPE_SECURITY;
+        if (OC_STACK_OK != AclToCBORPayload(aclData->acl, aclData->aclVersion, &secPayload->securityData,
+                                            &secPayload->payloadSize))
+        {
+            OCPayloadDestroy((OCPayload *)secPayload);
+            OIC_LOG(ERROR, TAG, "Failed to AclToCBORPayload");
+            OIC_LOG_V(ERROR, TAG, "OUT %s", __func__);
+            return OC_STACK_NO_MEMORY;
+        }
+        OIC_LOG(DEBUG, TAG, "Created payload for ACL:");
+        OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
+
+        char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
+        if (!PMGenerateQuery(true,
+                             aclData->deviceInfo->endpoint.addr,
+                             aclData->deviceInfo->securePort,
+                             aclData->deviceInfo->connType,
+                             query, sizeof(query), uri))
+        {
+            OIC_LOG(ERROR, TAG, "DeviceDiscoveryHandler : Failed to generate query");
+            return OC_STACK_ERROR;
+        }
+        OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
+
+        OCCallbackData cbData =  {.context = NULL, .cb = NULL, .cd = NULL};
+        cbData.cb = ProvisionCB;
+        cbData.context = ctx;
+        cbData.cd = NULL;
+        OCMethod method = OC_REST_POST;
+        OCDoHandle handle = NULL;
+        OIC_LOG(DEBUG, TAG, "Sending ACL info to resource server");
+        OCStackResult ret = OCDoResource(&handle, method, query,
+                                         &aclData->deviceInfo->endpoint, (OCPayload *)secPayload,
+                                         aclData->deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
+        if (ret != OC_STACK_OK)
+        {
+            OIC_LOG_V(ERROR, TAG, "OUT %s", __func__);
+            return OC_STACK_ERROR;
+        }
+    }
+    else
+    {
+        OIC_LOG_V(ERROR, TAG, "OUT %s", __func__);
+        return OC_STACK_ERROR;
+    }
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
+