Imported Upstream version 1.1.1
[platform/upstream/iotivity.git] / resource / csdk / security / src / amaclresource.c
1 //******************************************************************
2 //
3 // Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #include <stdlib.h>
22 #include <string.h>
23 #include "oic_malloc.h"
24 #include "ocpayload.h"
25 #include "payload_logging.h"
26 #include "psinterface.h"
27 #include "resourcemanager.h"
28 #include "utlist.h"
29 #include "srmresourcestrings.h"
30 #include "srmutility.h"
31 #include "amaclresource.h"
32
33 #define TAG  "SRM-AMACL"
34
35 /** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
36  * The value of payload size is increased until reaching belox max cbor size. */
37 static const uint16_t CBOR_SIZE = 1024;
38
39 /* Max cbor size payload. */
40 static const uint16_t CBOR_MAX_SIZE = 4400;
41
42 /** AMACL Map size - Number of mandatory items. */
43 static const uint8_t AMACL_MAP_SIZE = 3;
44 static const uint8_t AMACL_RSRC_MAP_SIZE = 1;
45 static const uint8_t AMACL_RLIST_MAP_SIZE = 3;
46
47 static OicSecAmacl_t *gAmacl = NULL;
48 static OCResourceHandle gAmaclHandle = NULL;
49
50 void DeleteAmaclList(OicSecAmacl_t* amacl)
51 {
52     if (amacl)
53     {
54         OicSecAmacl_t *amaclTmp1 = NULL, *amaclTmp2 = NULL;
55         LL_FOREACH_SAFE(amacl, amaclTmp1, amaclTmp2)
56         {
57             LL_DELETE(amacl, amaclTmp1);
58
59             // Clean Resources
60             for (size_t i = 0; i < amaclTmp1->resourcesLen; i++)
61             {
62                 OICFree(amaclTmp1->resources[i]);
63             }
64             OICFree(amaclTmp1->resources);
65
66             // Clean Amss
67             OICFree(amaclTmp1->amss);
68
69             // Clean Amacl node itself
70             OICFree(amaclTmp1);
71         }
72     }
73 }
74
75 OCStackResult AmaclToCBORPayload(const OicSecAmacl_t *amaclS, uint8_t **cborPayload,
76                                  size_t *cborSize)
77 {
78     if (NULL == amaclS || NULL == cborPayload || NULL != *cborPayload || NULL == cborSize)
79     {
80         return OC_STACK_INVALID_PARAM;
81     }
82
83     OCStackResult ret = OC_STACK_ERROR;
84     size_t cborLen = *cborSize;
85     if (0 == cborLen)
86     {
87         cborLen = CBOR_SIZE;
88     }
89
90     *cborSize = 0;
91     *cborPayload = NULL;
92
93     CborEncoder encoder;
94     CborEncoder amaclMap;
95     int64_t cborEncoderResult = CborNoError;
96     CborEncoder rsrcMap;
97     CborEncoder rlistArray;
98     CborEncoder amss;
99     char *stRowner = NULL;
100
101     const OicSecAmacl_t *amacl = amaclS;
102     uint8_t *outPayload = (uint8_t *)OICCalloc(1, cborLen);
103     VERIFY_NON_NULL(TAG, outPayload, ERROR);
104     cbor_encoder_init(&encoder, outPayload, cborLen, 0);
105
106     // Create AMACL Map
107     cborEncoderResult = cbor_encoder_create_map(&encoder, &amaclMap, AMACL_MAP_SIZE);
108     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding AMACL Map.");
109
110     // resources -- Mandatory
111     cborEncoderResult = cbor_encode_text_string(&amaclMap, OIC_JSON_RESOURCES_NAME,
112                 strlen(OIC_JSON_RESOURCES_NAME));
113     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Resource Name Tag.");
114
115     cborEncoderResult = cbor_encoder_create_map(&amaclMap, &rsrcMap, AMACL_RSRC_MAP_SIZE);
116     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Resource Map.");
117
118
119     cborEncoderResult = cbor_encode_text_string(&rsrcMap, OIC_JSON_RLIST_NAME,
120                 strlen(OIC_JSON_RLIST_NAME));
121     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RLIST Name Tag.");
122
123     // TODO : Need to input array length by OicSecAmacl_t->resources->rlistLen based on spec.
124     cborEncoderResult = cbor_encoder_create_array(&rsrcMap, &rlistArray, amacl->resourcesLen);
125     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RLIST Array.");
126
127     // TODO : Need to add OicSecAmacl_t->rlist as array rMap based on RAML spec.
128     for (size_t i = 0; i < amacl->resourcesLen; i++)
129     {
130         // TODO : Need to create rMap structure based on RAML spec.
131         CborEncoder rMap;
132         cborEncoderResult = cbor_encoder_create_map(&rlistArray, &rMap, AMACL_RLIST_MAP_SIZE);
133         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RLIST Map.");
134
135         cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_HREF_NAME,
136                 strlen(OIC_JSON_HREF_NAME));
137         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding HREF Name Tag.");
138         cborEncoderResult = cbor_encode_text_string(&rMap, amacl->resources[i],
139                 strlen(amacl->resources[i]));
140         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding HREF Value in Map.");
141
142         cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_RT_NAME,
143                 strlen(OIC_JSON_RT_NAME));
144         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
145
146         // TODO : Need to assign real value of RT
147         cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_EMPTY_STRING,
148                 strlen(OIC_JSON_EMPTY_STRING));
149         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Value.");
150
151         cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_IF_NAME,
152                 strlen(OIC_JSON_IF_NAME));
153         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
154
155         // TODO : Need to assign real value of IF
156         cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_EMPTY_STRING,
157                 strlen(OIC_JSON_EMPTY_STRING));
158         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
159
160         cborEncoderResult = cbor_encoder_close_container(&rlistArray, &rMap);
161         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing RLIST Array.");
162     }
163
164     cborEncoderResult = cbor_encoder_close_container(&rsrcMap, &rlistArray);
165     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing RLIST Array.");
166
167
168     cborEncoderResult = cbor_encoder_close_container(&amaclMap, &rsrcMap);
169     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Resource Map.");
170
171     // TODO : Need to modify type of OicSecAmacl_t->amss based on RAML spec.
172     // ams -- Mandatory
173     cborEncoderResult = cbor_encode_text_string(&amaclMap, OIC_JSON_AMS_NAME,
174                 strlen(OIC_JSON_AMS_NAME));
175     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding AMSS Name Tag.");
176
177     cborEncoderResult = cbor_encoder_create_array(&amaclMap, &amss, amacl->amssLen);
178     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding AMS Name Array.");
179     for (size_t i = 0; i < amacl->amssLen; i++)
180     {
181         cborEncoderResult = cbor_encode_text_string(&amss, (const char *)amacl->amss[i].id,
182             sizeof(amacl->amss[i].id));
183         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding AMS Name Value.");
184     }
185     cborEncoderResult = cbor_encoder_close_container(&amaclMap, &amss);
186     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing AMSS Array.");
187
188     // TODO : Need to check owner property in the RAML spec.
189     // rowner -- Mandatory
190     cborEncoderResult = cbor_encode_text_string(&amaclMap, OIC_JSON_ROWNERID_NAME,
191                 strlen(OIC_JSON_ROWNERID_NAME));
192     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding ROwnerID Name Tag.");
193
194     ret = ConvertUuidToStr(&amacl->rownerID, &stRowner);
195     VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
196     cborEncoderResult = cbor_encode_text_string(&amaclMap, stRowner, strlen(stRowner));
197     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding ROwner Value.");
198     OICFree(stRowner);
199
200     cborEncoderResult = cbor_encoder_close_container(&encoder, &amaclMap);
201     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Amacl Map.");
202
203     if (CborNoError == cborEncoderResult)
204     {
205         *cborPayload = outPayload;
206         *cborSize = encoder.ptr - outPayload;
207         ret = OC_STACK_OK;
208     }
209
210 exit:
211     if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE))
212     {
213        // reallocate and try again!
214        OICFree(outPayload);
215        outPayload = NULL;
216        // Since the allocated initial memory failed, double the memory.
217        cborLen += encoder.ptr - encoder.end;
218        cborEncoderResult = CborNoError;
219        ret = AmaclToCBORPayload(amaclS, cborPayload, &cborLen);
220        if (OC_STACK_OK == ret)
221        {
222            *cborSize = cborLen;
223            ret = OC_STACK_OK;
224        }
225     }
226
227     if (CborNoError != cborEncoderResult || ret != OC_STACK_OK)
228     {
229        OICFree(outPayload);
230        outPayload = NULL;
231        *cborSize = 0;
232        *cborPayload = NULL;
233        ret = OC_STACK_ERROR;
234     }
235
236     return ret;
237 }
238
239 OCStackResult CBORPayloadToAmacl(const uint8_t *cborPayload, size_t size,
240                                  OicSecAmacl_t **secAmacl)
241 {
242     if (NULL == cborPayload || NULL == secAmacl || NULL != *secAmacl || 0 == size)
243     {
244         return OC_STACK_INVALID_PARAM;
245     }
246
247     *secAmacl = NULL;
248
249     OCStackResult ret = OC_STACK_ERROR;
250
251     CborValue amaclCbor = { .parser = NULL };
252     CborParser parser = { .end = NULL };
253     CborError cborFindResult = CborNoError;
254
255     cbor_parser_init(cborPayload, size, 0, &parser, &amaclCbor);
256     OicSecAmacl_t *headAmacl = (OicSecAmacl_t *)OICCalloc(1, sizeof(OicSecAmacl_t));
257
258     CborValue amaclMap = { .parser = NULL };
259     cborFindResult = cbor_value_enter_container(&amaclCbor, &amaclMap);
260     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering Amacl Map.");
261
262     while(cbor_value_is_valid(&amaclMap) && cbor_value_is_text_string(&amaclMap))
263     {
264         char *name = NULL;
265         size_t len = 0;
266         cborFindResult = cbor_value_dup_text_string(&amaclMap, &name, &len, NULL);
267         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Amacl Data Name Tag.");
268         cborFindResult = cbor_value_advance(&amaclMap);
269         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Amacl Data Value.");
270
271         //CborType type = cbor_value_get_type(&amaclMap);
272
273         // Resources -- Mandatory
274         if (0 == strcmp(OIC_JSON_RESOURCES_NAME, name))
275         {
276             // resource map
277             CborValue rsrcMap = { .parser = NULL  };
278             cborFindResult = cbor_value_enter_container(&amaclMap, &rsrcMap);
279             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering Resource Map");
280
281             while(cbor_value_is_valid(&rsrcMap) && cbor_value_is_text_string(&rsrcMap))
282             {
283                 // resource name
284                 char *rsrcName = NULL;
285                 size_t rsrcNameLen = 0;
286                 cborFindResult = cbor_value_dup_text_string(&rsrcMap, &rsrcName, &rsrcNameLen, NULL);
287                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Resource Data Name Tag.");
288                 cborFindResult = cbor_value_advance(&rsrcMap);
289                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Resource Data Value.");
290
291                 // rlist
292                 if (0 == strcmp(OIC_JSON_RLIST_NAME, rsrcName))
293                 {
294                     int i = 0;
295                     // TODO : Need to assign array length to OicSecAmacl_t->resources->rlistLen based of RAML spec.
296                     cborFindResult = cbor_value_get_array_length(&rsrcMap, &headAmacl->resourcesLen);
297                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Rlist Array Len.");
298
299                     CborValue rsrcArray = { .parser = NULL  };
300
301                     // rlist array
302                     cborFindResult = cbor_value_enter_container(&rsrcMap, &rsrcArray);
303                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering Rlist Array");
304
305                     // TODO : Need to check data structure of OicSecAmacl_t based on RAML spec.
306                     headAmacl->resources = (char **) OICCalloc(headAmacl->resourcesLen, sizeof(*headAmacl->resources));
307                     VERIFY_NON_NULL(TAG, headAmacl->resources, ERROR);
308
309                     while (cbor_value_is_valid(&rsrcArray))
310                     {
311                         // rMap
312                         CborValue rMap = { .parser = NULL  };
313                         cborFindResult = cbor_value_enter_container(&rsrcArray, &rMap);
314                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering Rlist Map");
315
316                         while(cbor_value_is_valid(&rMap) && cbor_value_is_text_string(&rMap))
317                         {
318                             char *rMapName = NULL;
319                             size_t rMapNameLen = 0;
320                             cborFindResult = cbor_value_dup_text_string(&rMap, &rMapName, &rMapNameLen, NULL);
321                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Name Tag.");
322                             cborFindResult = cbor_value_advance(&rMap);
323                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Value.");
324
325                             // "href"
326                             if (0 == strcmp(OIC_JSON_HREF_NAME, rMapName))
327                             {
328                                 // TODO : Need to check data structure of OicSecAmacl_t based on RAML spec.
329                                 cborFindResult = cbor_value_dup_text_string(&rMap, &headAmacl->resources[i++], &len, NULL);
330                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Href Value.");
331                             }
332
333                             // "rt"
334                             if (0 == strcmp(OIC_JSON_RT_NAME, rMapName))
335                             {
336                                 // TODO : Need to check data structure of OicSecAmacl_t and assign based on RAML spec.
337                                 char *rtData = NULL;
338                                 cborFindResult = cbor_value_dup_text_string(&rMap, &rtData, &len, NULL);
339                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RT Value.");
340                                 OICFree(rtData);
341                             }
342
343                             // "if"
344                             if (0 == strcmp(OIC_JSON_IF_NAME, rMapName))
345                             {
346                                 // TODO : Need to check data structure of OicSecAmacl_t and assign based on RAML spec.
347                                 char *ifData = NULL;
348                                 cborFindResult = cbor_value_dup_text_string(&rMap, &ifData, &len, NULL);
349                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding IF Value.");
350                                 OICFree(ifData);
351                             }
352
353                             if (cbor_value_is_valid(&rMap))
354                             {
355                                 cborFindResult = cbor_value_advance(&rMap);
356                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Rlist Map.");
357                             }
358                             OICFree(rMapName);
359                         }
360
361                         if (cbor_value_is_valid(&rsrcArray))
362                         {
363                             cborFindResult = cbor_value_advance(&rsrcArray);
364                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Resource Array.");
365                         }
366                     }
367                 }
368
369                 if (cbor_value_is_valid(&rsrcMap))
370                 {
371                     cborFindResult = cbor_value_advance(&rsrcMap);
372                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Resource Map.");
373                 }
374                 OICFree(rsrcName);
375             }
376
377         }
378
379         // TODO : Need to modify type of OicSecAmacl_t->amss based on RAML spec.
380          // Ams -- Mandatory
381         if (0 == strcmp(OIC_JSON_AMS_NAME, name))
382         {
383             int i = 0;
384             CborValue amsArray = { .parser = NULL };
385             cborFindResult = cbor_value_get_array_length(&amaclMap, &headAmacl->amssLen);
386             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding AMS Array Len.");
387             cborFindResult = cbor_value_enter_container(&amaclMap, &amsArray);
388             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering AMS Array Container.");
389             headAmacl->amss = (OicUuid_t *)OICCalloc(headAmacl->amssLen, sizeof(*headAmacl->amss));
390             VERIFY_NON_NULL(TAG, headAmacl->amss, ERROR);
391             while (cbor_value_is_valid(&amsArray) && cbor_value_is_text_string(&amsArray))
392             {
393                 char *amssId = NULL;
394                 cborFindResult = cbor_value_dup_text_string(&amsArray, &amssId, &len, NULL);
395                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding AMS Id.");
396                 cborFindResult = cbor_value_advance(&amsArray);
397                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing AMS.");
398                 memcpy(headAmacl->amss[i++].id, (OicUuid_t *)amssId, len);
399                 OICFree(amssId);
400             }
401         }
402
403         // Rowner -- Mandatory
404         if (0 == strcmp(OIC_JSON_ROWNERID_NAME, name) && cbor_value_is_text_string(&amaclMap))
405         {
406             char *stRowner = NULL;
407             cborFindResult = cbor_value_dup_text_string(&amaclMap, &stRowner, &len, NULL);
408             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ROwner Value.");
409
410             ret = ConvertStrToUuid(stRowner, &headAmacl->rownerID);
411             VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
412             OICFree(stRowner);
413         }
414
415         //if (CborMapType != type && cbor_value_is_valid(&amaclMap))
416         if (cbor_value_is_valid(&amaclMap))
417         {
418             cborFindResult = cbor_value_advance(&amaclMap);
419             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Amacl Map.");
420         }
421         OICFree(name);
422     }
423
424     *secAmacl = headAmacl;
425     ret = OC_STACK_OK;
426
427 exit:
428     if (CborNoError != cborFindResult)
429     {
430         DeleteAmaclList(headAmacl);
431         headAmacl = NULL;
432         *secAmacl = NULL;
433         ret = OC_STACK_ERROR;
434     }
435     return ret;
436 }
437
438 static OCEntityHandlerResult HandleAmaclGetRequest (const OCEntityHandlerRequest * ehRequest)
439 {
440     // Convert Amacl data into JSON for transmission
441     size_t size = 0;
442     uint8_t *cborPayload = NULL;
443     OCStackResult res = AmaclToCBORPayload(gAmacl, &cborPayload, &size);
444
445     OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR;
446
447     // Send response payload to request originator
448     if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, cborPayload, size))
449     {
450         ehRet = OC_EH_ERROR;
451         OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandleAmaclGetRequest");
452     }
453     OICFree(cborPayload);
454
455     OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
456     return ehRet;
457 }
458
459 static OCEntityHandlerResult HandleAmaclPostRequest (const OCEntityHandlerRequest * ehRequest)
460 {
461     OCEntityHandlerResult ehRet = OC_EH_ERROR;
462
463     // Convert CBOR Amacl data into binary. This will also validate the Amacl data received.
464     uint8_t *payload = ((OCSecurityPayload *) ehRequest->payload)->securityData;
465     size_t size = ((OCSecurityPayload *) ehRequest->payload)->payloadSize;
466     if (payload)
467     {
468         OicSecAmacl_t *newAmacl = NULL;
469         OCStackResult res = CBORPayloadToAmacl(payload, size, &newAmacl);
470         if (newAmacl && OC_STACK_OK == res)
471         {
472             // Append the new Amacl to existing Amacl
473             LL_APPEND(gAmacl, newAmacl);
474             size_t size = 0;
475             // Convert Amacl data into JSON for update to persistent storage.
476             uint8_t *cborPayload = NULL;
477             res = AmaclToCBORPayload(gAmacl, &cborPayload, &size);
478             if (cborPayload && (OC_STACK_OK == res) &&
479                 (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_AMACL_NAME, cborPayload, size)))
480             {
481                 ehRet = OC_EH_CHANGED;
482             }
483             OICFree(cborPayload);
484         }
485         OICFree(payload);
486     }
487
488     // Send payload to request originator
489     if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL, 0))
490     {
491         ehRet = OC_EH_ERROR;
492         OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandleAmaclPostRequest");
493     }
494
495     OIC_LOG_V(DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
496     return ehRet;
497 }
498
499 /**
500  * This internal method is the entity handler for Amacl resources and
501  * will handle REST request (GET/PUT/POST/DEL) for them.
502  */
503 static OCEntityHandlerResult AmaclEntityHandler (OCEntityHandlerFlag flag,
504                                                  OCEntityHandlerRequest * ehRequest,
505                                                  void* callbackParameter)
506 {
507     (void) callbackParameter;
508     OCEntityHandlerResult ehRet = OC_EH_ERROR;
509
510     if (!ehRequest)
511     {
512         return ehRet;
513     }
514
515     if (flag & OC_REQUEST_FLAG)
516     {
517         OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
518         switch (ehRequest->method)
519         {
520             case OC_REST_GET:
521                 ehRet = HandleAmaclGetRequest(ehRequest);
522                 break;
523
524             case OC_REST_POST:
525                 ehRet = HandleAmaclPostRequest(ehRequest);
526                 break;
527
528             default:
529                 ehRet = OC_EH_ERROR;
530                 SendSRMResponse(ehRequest, ehRet, NULL, 0);
531         }
532     }
533
534     return ehRet;
535 }
536
537 /**
538  * This internal method is used to create '/oic/sec/amacl' resource.
539  */
540 static OCStackResult CreateAmaclResource()
541 {
542     OCStackResult ret = OCCreateResource(&gAmaclHandle,
543                                          OIC_RSRC_TYPE_SEC_AMACL,
544                                          OC_RSRVD_INTERFACE_DEFAULT,
545                                          OIC_RSRC_AMACL_URI,
546                                          AmaclEntityHandler,
547                                          NULL,
548                                          OC_OBSERVABLE);
549
550     if (OC_STACK_OK != ret)
551     {
552         OIC_LOG (FATAL, TAG, "Unable to instantiate Amacl resource");
553         DeInitAmaclResource();
554     }
555     return ret;
556 }
557
558 OCStackResult InitAmaclResource()
559 {
560     OCStackResult ret = OC_STACK_ERROR;
561
562     uint8_t *data = NULL;
563     size_t size = 0;
564     ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_AMACL_NAME, &data, &size);
565
566     // If database read failed
567     if (OC_STACK_OK != ret)
568     {
569         OIC_LOG(DEBUG, TAG, "ReadSVDataFromPS failed");
570     }
571     if (data)
572     {
573         // Read AMACL resource from PS
574         ret = CBORPayloadToAmacl(data, size, &gAmacl);
575         if (OC_STACK_OK != ret)
576         {
577             OIC_LOG(DEBUG, TAG, "ReadAMACLresourcefromPS failed");
578         }
579         OICFree(data);
580     }
581
582     // Instantiate 'oic/sec/amacl' resource
583     ret = CreateAmaclResource();
584
585     if (OC_STACK_OK != ret)
586     {
587         DeInitAmaclResource();
588     }
589     return ret;
590 }
591
592 void DeInitAmaclResource()
593 {
594     OCDeleteResource(gAmaclHandle);
595     gAmaclHandle = NULL;
596
597     DeleteAmaclList(gAmacl);
598     gAmacl = NULL;
599 }
600
601 OCStackResult AmaclGetAmsDeviceId(const char *resource, OicUuid_t *amsDeviceId)
602 {
603     OicSecAmacl_t *amacl = NULL;
604
605     VERIFY_NON_NULL(TAG, resource, ERROR);
606     VERIFY_NON_NULL(TAG, amsDeviceId, ERROR);
607
608     LL_FOREACH(gAmacl, amacl)
609     {
610         for(size_t i = 0; i < amacl->resourcesLen; i++)
611         {
612             if (0 == strncmp((amacl->resources[i]), resource, strlen(amacl->resources[i])))
613             {
614                 //Returning the ID of the first AMS service for the resource
615                 memcpy(amsDeviceId, &amacl->amss[0], sizeof(*amsDeviceId));
616                 return OC_STACK_OK;
617             }
618         }
619     }
620
621 exit:
622     return OC_STACK_ERROR;
623 }
624
625 OCStackResult SetAmaclRownerId(const OicUuid_t* newROwner)
626 {
627     OCStackResult ret = OC_STACK_ERROR;
628     uint8_t *cborPayload = NULL;
629     size_t size = 0;
630     OicUuid_t prevId = {.id={0}};
631
632     if(NULL == newROwner)
633     {
634         ret = OC_STACK_INVALID_PARAM;
635     }
636     if(NULL == gAmacl)
637     {
638         ret = OC_STACK_NO_RESOURCE;
639     }
640
641     if(newROwner && gAmacl)
642     {
643         memcpy(prevId.id, gAmacl->rownerID.id, sizeof(prevId.id));
644         memcpy(gAmacl->rownerID.id, newROwner->id, sizeof(newROwner->id));
645
646         ret = AmaclToCBORPayload(gAmacl, &cborPayload, &size);
647         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
648
649         ret = UpdateSecureResourceInPS(OIC_JSON_AMACL_NAME, cborPayload, size);
650         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
651
652         OICFree(cborPayload);
653     }
654
655     return ret;
656
657 exit:
658     OICFree(cborPayload);
659     memcpy(gAmacl->rownerID.id, prevId.id, sizeof(prevId.id));
660     return ret;
661 }
662
663 OCStackResult GetAmaclRownerId(OicUuid_t *rowneruuid)
664 {
665     OCStackResult retVal = OC_STACK_ERROR;
666     if (gAmacl)
667     {
668         *rowneruuid = gAmacl->rownerID;
669         retVal = OC_STACK_OK;
670     }
671     return retVal;
672 }