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