Fixed acl update issues
[platform/upstream/iotivity.git] / resource / csdk / security / src / aclresource.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 "iotivity_config.h"
22 #ifdef HAVE_STRING_H
23 #include <string.h>
24 #elif defined(HAVE_STRINGS_H)
25 #include <strings.h>
26 #endif
27 #include <stdlib.h>
28
29 #include "utlist.h"
30 #include "ocstack.h"
31 #include "octypes.h"
32 #include "ocserverrequest.h"
33 #include "oic_malloc.h"
34 #include "oic_string.h"
35 #include "ocrandom.h"
36 #include "ocpayload.h"
37 #include "utlist.h"
38 #include "payload_logging.h"
39 #include "srmresourcestrings.h"
40 #include "aclresource.h"
41 #include "doxmresource.h"
42 #include "resourcemanager.h"
43 #include "srmutility.h"
44 #include "psinterface.h"
45 #include "ocpayloadcbor.h"
46
47 #include "security_internals.h"
48
49 #define TAG  "OIC_SRM_ACL"
50 #define NUMBER_OF_SEC_PROV_RSCS 3
51 #define NUMBER_OF_DEFAULT_SEC_RSCS 2
52 #define STRING_UUID_SIZE (UUID_LENGTH * 2 + 5)
53
54 static const uint8_t ACL_MAP_SIZE = 4;
55 static const uint8_t ACL_ACLIST_MAP_SIZE = 1;
56 static const uint8_t ACL_ACES_MAP_SIZE = 3;
57 static const uint8_t ACL_RESOURCE_MAP_SIZE = 3;
58
59
60 // CborSize is the default cbor payload size being used.
61 static const uint16_t CBOR_SIZE = 2048*8;
62
63 static OicSecAcl_t *gAcl = NULL;
64 static OCResourceHandle gAclHandle = NULL;
65
66 void FreeRsrc(OicSecRsrc_t *rsrc)
67 {
68     //Clean each member of resource
69     OICFree(rsrc->href);
70     OICFree(rsrc->rel);
71     //Clean "rt"
72     if(0 < rsrc->typeLen && rsrc->types)
73     {
74         for(size_t i = 0; i < rsrc->typeLen; i++)
75         {
76             OICFree(rsrc->types[i]);
77         }
78         OICFree(rsrc->types);
79         rsrc->types = NULL;
80     }
81     //Clean "if"
82     if(0 < rsrc->interfaceLen && rsrc->interfaces)
83     {
84         for(size_t i = 0; i < rsrc->interfaceLen; i++)
85         {
86             OICFree(rsrc->interfaces[i]);
87         }
88         OICFree(rsrc->interfaces);
89         rsrc->interfaces = NULL;
90     }
91     OICFree(rsrc);
92     rsrc = NULL;
93 }
94
95 /**
96  * This function frees OicSecAcl_t object's fields and object itself.
97  */
98 static void FreeACE(OicSecAce_t *ace)
99 {
100     if (NULL == ace)
101     {
102         OIC_LOG(ERROR, TAG, "Invalid Parameter");
103         return;
104     }
105
106     //Clean Resources
107     OicSecRsrc_t* rsrc = NULL;
108     OicSecRsrc_t* tmpRsrc = NULL;
109     LL_FOREACH_SAFE(ace->resources, rsrc, tmpRsrc)
110     {
111         LL_DELETE(ace->resources, rsrc);
112         FreeRsrc(rsrc);
113     }
114
115     //Clean Validities
116     OicSecValidity_t *validity = NULL;
117     OicSecValidity_t *tmpValidity = NULL;
118     LL_FOREACH_SAFE(ace->validities, validity, tmpValidity)
119     {
120         LL_DELETE(ace->validities, validity);
121
122         //Clean period
123         OICFree(validity->period);
124
125         //Clean recurrence
126         for(size_t i = 0; i < validity->recurrenceLen; i++)
127         {
128             OICFree(validity->recurrences[i]);
129         }
130         OICFree(validity->recurrences);
131         OICFree(validity);
132         validity = NULL;
133     }
134
135 #ifdef MULTIPLE_OWNER
136     OICFree(ace->eownerID);
137 #endif
138
139     //Clean ACE
140     OICFree(ace);
141     ace = NULL;
142 }
143
144 void DeleteACLList(OicSecAcl_t* acl)
145 {
146     if (acl)
147     {
148         OicSecAce_t *ace = NULL;
149         OicSecAce_t *tmpAce = NULL;
150         LL_FOREACH_SAFE(acl->aces, ace, tmpAce)
151         {
152             LL_DELETE(acl->aces, ace);
153             FreeACE(ace);
154         }
155         acl->aces = NULL;
156         OICFree(acl);
157     }
158 }
159
160 OicSecAce_t* DuplicateACE(const OicSecAce_t* ace)
161 {
162     OicSecAce_t* newAce = NULL;
163     size_t allocateSize = 0;
164
165     if(ace)
166     {
167         newAce = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
168         VERIFY_NON_NULL(TAG, newAce, ERROR);
169
170         //Subject uuid
171         memcpy(&newAce->subjectuuid, &ace->subjectuuid, sizeof(OicUuid_t));
172
173         OicSecRsrc_t* rsrc = NULL;
174         LL_FOREACH(ace->resources, rsrc)
175         {
176             OicSecRsrc_t* newRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
177             VERIFY_NON_NULL(TAG, newRsrc, ERROR);
178             LL_APPEND(newAce->resources, newRsrc);
179
180             //href is mandatory
181             VERIFY_NON_NULL(TAG, rsrc->href, ERROR);
182             allocateSize = strlen(rsrc->href) + 1;
183             newRsrc->href = (char*)OICMalloc(sizeof(char) * allocateSize);
184             VERIFY_NON_NULL(TAG, newRsrc->href, ERROR);
185             OICStrcpy(newRsrc->href, allocateSize, rsrc->href);
186
187             if(rsrc->rel)
188             {
189                 allocateSize = strlen(rsrc->rel) + 1;
190                 newRsrc->rel = (char*)OICMalloc(sizeof(char) * allocateSize);
191                 VERIFY_NON_NULL(TAG, newRsrc->rel, ERROR);
192                 OICStrcpy(newRsrc->rel, allocateSize, rsrc->rel);
193                 newRsrc->rel[allocateSize - 1] = '\0';
194             }
195
196             if(rsrc->types && 0 < rsrc->typeLen)
197             {
198                 newRsrc->typeLen = rsrc->typeLen;
199                 newRsrc->types = (char**)OICCalloc(rsrc->typeLen, sizeof(char*));
200                 VERIFY_NON_NULL(TAG, (newRsrc->types), ERROR);
201                 for(size_t i = 0; i < rsrc->typeLen; i++)
202                 {
203                     newRsrc->types[i] = OICStrdup(rsrc->types[i]);
204                     VERIFY_NON_NULL(TAG, (newRsrc->types[i]), ERROR);
205                 }
206             }
207
208             if(rsrc->interfaces && 0 < rsrc->interfaceLen)
209             {
210                 newRsrc->interfaceLen = rsrc->interfaceLen;
211                 newRsrc->interfaces = (char**)OICCalloc(rsrc->interfaceLen, sizeof(char*));
212                 VERIFY_NON_NULL(TAG, (newRsrc->interfaces), ERROR);
213                 for(size_t i = 0; i < rsrc->interfaceLen; i++)
214                 {
215                     newRsrc->interfaces[i] = OICStrdup(rsrc->interfaces[i]);
216                     VERIFY_NON_NULL(TAG, (newRsrc->interfaces[i]), ERROR);
217                 }
218             }
219         }
220
221         //Permission
222         newAce->permission = ace->permission;
223
224         //Validity
225         if(ace->validities)
226         {
227             OicSecValidity_t* validity = NULL;
228             LL_FOREACH(ace->validities, validity)
229             {
230                 OicSecValidity_t* newValidity = (OicSecValidity_t*)OICCalloc(1, sizeof(OicSecValidity_t));
231                 VERIFY_NON_NULL(TAG, newValidity, ERROR);
232                 LL_APPEND(newAce->validities, newValidity);
233
234                 if(validity->period)
235                 {
236                     allocateSize = strlen(validity->period) + 1;
237                     newValidity->period = (char*)OICMalloc(sizeof(char) * allocateSize);
238                     VERIFY_NON_NULL(TAG, newValidity->period, ERROR);
239                     OICStrcpy(newValidity->period, allocateSize, validity->period);
240                 }
241
242                 if(validity->recurrences && 0 < validity->recurrenceLen)
243                 {
244                     newValidity->recurrenceLen = validity->recurrenceLen;
245
246                     newValidity->recurrences = (char**)OICMalloc(sizeof(char*) * validity->recurrenceLen);
247                     VERIFY_NON_NULL(TAG, newValidity->recurrences, ERROR);
248
249                     for(size_t i = 0; i < validity->recurrenceLen; i++)
250                     {
251                         allocateSize = strlen(validity->recurrences[i]) + 1;
252                         newValidity->recurrences[i] = (char*)OICMalloc(sizeof(char) * allocateSize);
253                         VERIFY_NON_NULL(TAG, (newValidity->recurrences[i]), ERROR);
254                         OICStrcpy(newValidity->recurrences[i], allocateSize, validity->recurrences[i]);
255                     }
256                 }
257             }
258         }
259
260 #ifdef MULTIPLE_OWNER
261         if (ace->eownerID)
262         {
263             if (NULL == newAce->eownerID)
264             {
265                 newAce->eownerID = (OicUuid_t*)OICCalloc(1, sizeof(OicUuid_t));
266                 VERIFY_NON_NULL(TAG, (newAce->eownerID), ERROR);
267             }
268             memcpy(newAce->eownerID->id, ace->eownerID->id, sizeof(ace->eownerID->id));
269         }
270 #endif
271
272         newAce->next = NULL;
273     }
274
275     return newAce;
276
277 exit:
278     FreeACE(newAce);
279     return NULL;
280 }
281
282 static size_t OicSecAclSize(const OicSecAcl_t *secAcl)
283 {
284     if (!secAcl)
285     {
286         return 0;
287     }
288     OicSecAce_t *ace= (OicSecAce_t *)secAcl->aces;
289     size_t size = 0;
290     while (ace)
291     {
292        size++;
293        ace = ace->next;
294     }
295     return size;
296 }
297
298 OCStackResult AclToCBORPayload(const OicSecAcl_t *secAcl, uint8_t **payload, size_t *size)
299 {
300      if (NULL == secAcl || NULL == payload || NULL != *payload || NULL == size)
301     {
302         return OC_STACK_INVALID_PARAM;
303     }
304
305     OCStackResult ret = OC_STACK_ERROR;
306     CborError cborEncoderResult = CborNoError;
307     OicSecAcl_t *acl = (OicSecAcl_t *)secAcl;
308     OicSecAce_t* ace = NULL;
309     CborEncoder encoder;
310     CborEncoder aclMap;
311     CborEncoder aclListMap;
312     CborEncoder acesArray;
313     uint8_t *outPayload = NULL;
314     size_t cborLen = *size;
315     *size = 0;
316     *payload = NULL;
317
318     if (cborLen == 0)
319     {
320         cborLen = CBOR_SIZE;
321     }
322
323     outPayload = (uint8_t *)OICCalloc(1, cborLen);
324     VERIFY_NON_NULL(TAG, outPayload, ERROR);
325     cbor_encoder_init(&encoder, outPayload, cborLen, 0);
326
327     // Create ACL Map (aclist, rownerid)
328     cborEncoderResult = cbor_encoder_create_map(&encoder, &aclMap, ACL_MAP_SIZE);
329     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating ACL Map.");
330
331     cborEncoderResult = cbor_encode_text_string(&aclMap, OIC_JSON_ACLIST_NAME,
332         strlen(OIC_JSON_ACLIST_NAME));
333     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding aclist Name Tag.");
334
335     // Create ACLIST Map (aces)
336     cborEncoderResult = cbor_encoder_create_map(&aclMap, &aclListMap, ACL_ACLIST_MAP_SIZE);
337     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating ACLIST Map.");
338
339     cborEncoderResult = cbor_encode_text_string(&aclListMap, OIC_JSON_ACES_NAME,
340         strlen(OIC_JSON_ACES_NAME));
341     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACES Name Tag.");
342
343     // Create ACES Array
344     cborEncoderResult = cbor_encoder_create_array(&aclListMap, &acesArray, OicSecAclSize(secAcl));
345     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating ACES Array.");
346
347     ace = NULL;
348     LL_FOREACH (acl->aces, ace)
349     {
350         CborEncoder oicSecAclMap;
351         // ACL Map size - Number of mandatory items
352         uint8_t aclMapSize = ACL_ACES_MAP_SIZE;
353         size_t inLen = 0;
354
355         OicSecValidity_t* validityElts = ace->validities;
356         while(validityElts)
357         {
358             if(validityElts->period)
359             {
360                 aclMapSize++;
361             }
362             if(validityElts->recurrences)
363             {
364                 aclMapSize++;
365             }
366             validityElts = validityElts->next;
367         }
368
369 #ifdef MULTIPLE_OWNER
370         if(ace->eownerID)
371         {
372             aclMapSize++;
373         }
374 #endif //MULTIPLE_OWNER
375
376         cborEncoderResult = cbor_encoder_create_map(&acesArray, &oicSecAclMap, aclMapSize);
377         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating ACES Map");
378
379         // Subject -- Mandatory
380         cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, OIC_JSON_SUBJECTID_NAME,
381             strlen(OIC_JSON_SUBJECTID_NAME));
382         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Subject Name Tag.");
383         inLen = (memcmp(&(ace->subjectuuid), &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t)) == 0) ?
384             WILDCARD_SUBJECT_ID_LEN : sizeof(OicUuid_t);
385         if(inLen == WILDCARD_SUBJECT_ID_LEN)
386         {
387             cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, WILDCARD_RESOURCE_URI,
388                 strlen(WILDCARD_RESOURCE_URI));
389             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id wildcard Value.");
390         }
391         else
392         {
393             char *subject = NULL;
394             ret = ConvertUuidToStr(&ace->subjectuuid, &subject);
395             VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
396             cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, subject, strlen(subject));
397             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject UUID Value.");
398             OICFree(subject);
399         }
400
401         // Resources
402         {
403             CborEncoder resources;
404             cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, OIC_JSON_RESOURCES_NAME,
405                 strlen(OIC_JSON_RESOURCES_NAME));
406             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Resource Name Tag.");
407
408             size_t rsrcLen = 0;
409             OicSecRsrc_t* rsrcElts = NULL;
410             LL_FOREACH(ace->resources, rsrcElts)
411             {
412                 rsrcLen++;
413             }
414
415             cborEncoderResult = cbor_encoder_create_array(&oicSecAclMap, &resources, rsrcLen);
416             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Resource Name Array.");
417
418             OicSecRsrc_t* rsrc = NULL;
419             LL_FOREACH(ace->resources, rsrc)
420             {
421
422                 CborEncoder rMap;
423                 size_t rsrcMapSize = ACL_RESOURCE_MAP_SIZE;
424                 if(rsrc->rel)
425                 {
426                     rsrcMapSize++;
427                 }
428
429                 cborEncoderResult = cbor_encoder_create_map(&resources, &rMap, rsrcMapSize);
430                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Resource Map.");
431
432                 //href -- Mandatory
433                 VERIFY_NON_NULL(TAG, rsrc->href, ERROR);
434                 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_HREF_NAME,
435                         strlen(OIC_JSON_HREF_NAME));
436                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding HREF Name Tag.");
437                 cborEncoderResult = cbor_encode_text_string(&rMap, rsrc->href, strlen(rsrc->href));
438                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding HREF Value in Map.");
439
440                 //resource type -- Mandatory
441                 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_RT_NAME,
442                         strlen(OIC_JSON_RT_NAME));
443                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
444
445                 CborEncoder resourceTypes;
446                 cborEncoderResult = cbor_encoder_create_array(&rMap, &resourceTypes, rsrc->typeLen);
447                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding RT Array.");
448                 for(size_t i = 0; i < rsrc->typeLen; i++)
449                 {
450                     cborEncoderResult = cbor_encode_text_string(&resourceTypes, rsrc->types[i], strlen(rsrc->types[i]));
451                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Value.");
452                 }
453                 cborEncoderResult = cbor_encoder_close_container(&rMap, &resourceTypes);
454                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing resourceTypes.");
455
456                 //interface -- Mandatory
457                 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_IF_NAME,
458                         strlen(OIC_JSON_IF_NAME));
459                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
460
461                 CborEncoder interfaces;
462                 cborEncoderResult = cbor_encoder_create_array(&rMap, &interfaces, rsrc->interfaceLen);
463                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding IF Array.");
464                 for(size_t i = 0; i < rsrc->interfaceLen; i++)
465                 {
466                     cborEncoderResult = cbor_encode_text_string(&interfaces, rsrc->interfaces[i], strlen(rsrc->interfaces[i]));
467                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
468                 }
469                 cborEncoderResult = cbor_encoder_close_container(&rMap, &interfaces);
470                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing interfaces.");
471
472                 //rel
473                 if(rsrc->rel)
474                 {
475                     cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_REL_NAME,
476                             strlen(OIC_JSON_REL_NAME));
477                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding REL Name Tag.");
478                     cborEncoderResult = cbor_encode_text_string(&rMap, rsrc->rel, strlen(rsrc->rel));
479                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding REL Value.");
480                 }
481
482                 cborEncoderResult = cbor_encoder_close_container(&resources, &rMap);
483                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Resource Map.");
484             }
485             cborEncoderResult = cbor_encoder_close_container(&oicSecAclMap, &resources);
486             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Resource Name Array.");
487         }
488
489         // Permissions -- Mandatory
490         cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, OIC_JSON_PERMISSION_NAME,
491             strlen(OIC_JSON_PERMISSION_NAME));
492         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Permission Name Tag.");
493         cborEncoderResult = cbor_encode_int(&oicSecAclMap, ace->permission);
494         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Permission Name Value.");
495
496         // TODO: Need to verfication for validity
497         // Validity(Time-interval) -- Not Mandatory
498         if(ace->validities)
499         {
500             size_t validityLen = 0;
501             validityElts = NULL;
502             LL_FOREACH(ace->validities, validityElts)
503             {
504                 validityLen++;
505             }
506
507             CborEncoder validities;
508             cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, OIC_JSON_VALIDITY_NAME,
509                 strlen(OIC_JSON_VALIDITY_NAME));
510             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Validity Tag.");
511             cborEncoderResult = cbor_encoder_create_array(&oicSecAclMap, &validities, validityLen);
512             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Validities Array.");
513
514             //How to add the value w/o "title" using tinycobr...? :(
515
516             validityElts = NULL;
517             LL_FOREACH(ace->validities, validityElts)
518             {
519                  CborEncoder validity;
520                  size_t validitySize = 0;
521                  if(validityElts->period)
522                 {
523                     validitySize++;
524                 }
525                 if(validityElts->recurrences)
526                 {
527                     validitySize++;
528                 }
529
530                 cborEncoderResult = cbor_encoder_create_array(&validities, &validity, validitySize);
531                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Validity Array.");
532
533                 // Period
534                 if (validityElts->period)
535                 {
536                     cborEncoderResult = cbor_encode_text_string(&validity, validityElts->period,
537                         strlen(validityElts->period));
538                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Value.");
539                 }
540
541                 // Recurrence
542                 if (validityElts->recurrences)
543                 {
544                     CborEncoder recurrences;
545                     cborEncoderResult = cbor_encoder_create_array(&validity, &recurrences, validityElts->recurrenceLen);
546                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Recurrence Array.");
547
548                     for (size_t i = 0; i < validityElts->recurrenceLen; i++)
549                     {
550                         cborEncoderResult = cbor_encode_text_string(&recurrences, validityElts->recurrences[i],
551                             strlen(validityElts->recurrences[i]));
552                         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Recurrence Array Value.");
553                     }
554                     cborEncoderResult = cbor_encoder_close_container(&validity, &recurrences);
555                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Recurrence Array");
556                 }
557
558                 cborEncoderResult = cbor_encoder_close_container(&validities, &validity);
559                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Validity Array.");
560             }
561
562             cborEncoderResult = cbor_encoder_close_container(&oicSecAclMap, &validities);
563             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Validities Array.");
564         }
565
566 #ifdef MULTIPLE_OWNER
567         // Eownerid -- Not Mandatory
568         if(ace->eownerID)
569         {
570             char *eowner = NULL;
571             cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, OIC_JSON_EOWNERID_NAME,
572                 strlen(OIC_JSON_EOWNERID_NAME));
573             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding eownerId Name Tag.");
574             ret = ConvertUuidToStr(ace->eownerID, &eowner);
575             VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
576             cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, eowner, strlen(eowner));
577             OICFree(eowner);
578             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding eownerId Value.");
579         }
580 #endif //MULTIPLE_OWNER
581
582         cborEncoderResult = cbor_encoder_close_container(&acesArray, &oicSecAclMap);
583         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing ACES Map.");
584     }
585
586     // Close ACES Array
587     cborEncoderResult = cbor_encoder_close_container(&aclListMap, &acesArray);
588     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing ACES Array.");
589
590     // Close ACLIST Map
591     cborEncoderResult = cbor_encoder_close_container(&aclMap, &aclListMap);
592     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing ACLIST Map.");
593
594     // Rownerid
595     {
596         char *rowner = NULL;
597         cborEncoderResult = cbor_encode_text_string(&aclMap, OIC_JSON_ROWNERID_NAME,
598             strlen(OIC_JSON_ROWNERID_NAME));
599         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding rownerid Name.");
600         ret = ConvertUuidToStr(&secAcl->rownerID, &rowner);
601         VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
602         cborEncoderResult = cbor_encode_text_string(&aclMap, rowner, strlen(rowner));
603         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding rownerid Value.");
604         OICFree(rowner);
605     }
606
607     //RT -- Mandatory
608     CborEncoder rtArray;
609     cborEncoderResult = cbor_encode_text_string(&aclMap, OIC_JSON_RT_NAME,
610             strlen(OIC_JSON_RT_NAME));
611     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
612     cborEncoderResult = cbor_encoder_create_array(&aclMap, &rtArray, 1);
613     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Value.");
614     for (size_t i = 0; i < 1; i++)
615     {
616         cborEncoderResult = cbor_encode_text_string(&rtArray, OIC_RSRC_TYPE_SEC_ACL,
617                 strlen(OIC_RSRC_TYPE_SEC_ACL));
618         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding RT Value.");
619     }
620     cborEncoderResult = cbor_encoder_close_container(&aclMap, &rtArray);
621     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing RT.");
622
623     //IF-- Mandatory
624     CborEncoder ifArray;
625     cborEncoderResult = cbor_encode_text_string(&aclMap, OIC_JSON_IF_NAME,
626              strlen(OIC_JSON_IF_NAME));
627     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
628     cborEncoderResult = cbor_encoder_create_array(&aclMap, &ifArray, 1);
629     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
630     for (size_t i = 0; i < 1; i++)
631     {
632         cborEncoderResult = cbor_encode_text_string(&ifArray, OC_RSRVD_INTERFACE_DEFAULT,
633                 strlen(OC_RSRVD_INTERFACE_DEFAULT));
634         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding IF Value.");
635     }
636     cborEncoderResult = cbor_encoder_close_container(&aclMap, &ifArray);
637     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing IF.");
638
639     // Close ACL Map
640     cborEncoderResult = cbor_encoder_close_container(&encoder, &aclMap);
641     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing ACL Map.");
642
643     if (CborNoError == cborEncoderResult)
644     {
645         OIC_LOG(DEBUG, TAG, "AclToCBORPayload Successed");
646         *size = cbor_encoder_get_buffer_size(&encoder, outPayload);
647         *payload = outPayload;
648         ret = OC_STACK_OK;
649     }
650 exit:
651     if (CborErrorOutOfMemory == cborEncoderResult)
652     {
653         OIC_LOG(DEBUG, TAG, "AclToCBORPayload:CborErrorOutOfMemory : retry with more memory");
654
655         // reallocate and try again!
656         OICFree(outPayload);
657         // Since the allocated initial memory failed, double the memory.
658         cborLen += cbor_encoder_get_buffer_size(&encoder, encoder.end);
659         cborEncoderResult = CborNoError;
660         ret = AclToCBORPayload(secAcl, payload, &cborLen);
661         *size = cborLen;
662     }
663     else if (cborEncoderResult != CborNoError)
664     {
665         OIC_LOG(ERROR, TAG, "Failed to AclToCBORPayload");
666         OICFree(outPayload);
667         outPayload = NULL;
668         *size = 0;
669         *payload = NULL;
670         ret = OC_STACK_ERROR;
671     }
672
673     return ret;
674 }
675
676 // This function converts CBOR format to ACL data.
677 // Caller needs to invoke 'free' when done using
678 // It parses { "aclist" : [ { ... } ] } instead of { "aclist" : { "aces" : [ ] } }
679 OicSecAcl_t* CBORPayloadToAcl2(const uint8_t *cborPayload, const size_t size)
680 {
681     if (NULL == cborPayload || 0 == size)
682     {
683         return NULL;
684     }
685     OCStackResult ret = OC_STACK_ERROR;
686     CborValue aclCbor = { .parser = NULL };
687     CborParser parser = { .end = NULL };
688     CborError cborFindResult = CborNoError;
689     cbor_parser_init(cborPayload, size, 0, &parser, &aclCbor);
690
691     OicSecAcl_t *acl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
692     VERIFY_NON_NULL(TAG, acl, ERROR);
693
694     // Enter ACL Map
695     CborValue aclMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
696     cborFindResult = cbor_value_enter_container(&aclCbor, &aclMap);
697     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACL Map.");
698
699     while (cbor_value_is_valid(&aclMap))
700     {
701         char* tagName = NULL;
702         size_t len = 0;
703         CborType type = cbor_value_get_type(&aclMap);
704         if (type == CborTextStringType)
705         {
706             cborFindResult = cbor_value_dup_text_string(&aclMap, &tagName, &len, NULL);
707             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in ACL Map.");
708             cborFindResult = cbor_value_advance(&aclMap);
709             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in ACL Map.");
710         }
711         if(tagName)
712         {
713             if (strcmp(tagName, OIC_JSON_ACLIST_NAME)  == 0)
714             {
715                 // Enter ACES Array
716                 CborValue acesArray = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
717                 cborFindResult = cbor_value_enter_container(&aclMap, &acesArray);
718                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACES Array.");
719
720                 int acesCount = 0;
721                 while (cbor_value_is_valid(&acesArray))
722                 {
723                     acesCount++;
724                     CborValue aceMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
725                     cborFindResult = cbor_value_enter_container(&acesArray, &aceMap);
726                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACE Map.");
727
728                     OicSecAce_t *ace = NULL;
729                     ace = (OicSecAce_t *) OICCalloc(1, sizeof(OicSecAce_t));
730                     VERIFY_NON_NULL(TAG, ace, ERROR);
731                     LL_APPEND(acl->aces, ace);
732
733                     while (cbor_value_is_valid(&aceMap))
734                     {
735                         char* name = NULL;
736                         size_t len = 0;
737                         CborType type = cbor_value_get_type(&aceMap);
738                         if (type == CborTextStringType)
739                         {
740                             cborFindResult = cbor_value_dup_text_string(&aceMap, &name, &len, NULL);
741                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in ACE Map.");
742                             cborFindResult = cbor_value_advance(&aceMap);
743                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in ACE Map.");
744                         }
745                         if (name)
746                         {
747                             // Subject -- Mandatory
748                             if (strcmp(name, OIC_JSON_SUBJECTID_NAME)  == 0)
749                             {
750                                 char *subject = NULL;
751                                 cborFindResult = cbor_value_dup_text_string(&aceMap, &subject, &len, NULL);
752                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding subject Value.");
753                                 if(strcmp(subject, WILDCARD_RESOURCE_URI) == 0)
754                                 {
755                                     ace->subjectuuid.id[0] = '*';
756                                 }
757                                 else
758                                 {
759                                     OIC_LOG_V(DEBUG, TAG, "Converting subjectuuid = %s to uuid...", subject);
760                                     ret = ConvertStrToUuid(subject, &ace->subjectuuid);
761                                     VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
762                                 }
763                                 OICFree(subject);
764                             }
765
766                             // Resources -- Mandatory
767                             if (strcmp(name, OIC_JSON_RESOURCES_NAME) == 0)
768                             {
769                                 CborValue resources = { .parser = NULL };
770                                 cborFindResult = cbor_value_enter_container(&aceMap, &resources);
771                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering a Resource Array.");
772
773                                 while (cbor_value_is_valid(&resources))
774                                 {
775                                     // rMap
776                                     CborValue rMap = { .parser = NULL  };
777                                     cborFindResult = cbor_value_enter_container(&resources, &rMap);
778                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering Resource Map");
779
780                                     OicSecRsrc_t* rsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
781                                     VERIFY_NON_NULL(TAG, rsrc, ERROR);
782                                     LL_APPEND(ace->resources, rsrc);
783
784                                     while(cbor_value_is_valid(&rMap))
785                                     {
786                                         char *rMapName = NULL;
787                                         size_t rMapNameLen = 0;
788                                         cborFindResult = cbor_value_dup_text_string(&rMap, &rMapName, &rMapNameLen, NULL);
789                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Name Tag.");
790                                         cborFindResult = cbor_value_advance(&rMap);
791                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Value.");
792
793                                         // "href"
794                                         if (0 == strcmp(OIC_JSON_HREF_NAME, rMapName))
795                                         {
796                                             cborFindResult = cbor_value_dup_text_string(&rMap, &rsrc->href, &len, NULL);
797                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Href Value.");
798                                         }
799
800                                         // "rt"
801                                         if (0 == strcmp(OIC_JSON_RT_NAME, rMapName) && cbor_value_is_array(&rMap))
802                                         {
803                                             cbor_value_get_array_length(&rMap, &rsrc->typeLen);
804                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RT array length.");
805                                             VERIFY_SUCCESS(TAG, (0 != rsrc->typeLen), ERROR);
806
807                                             rsrc->types = (char**)OICCalloc(rsrc->typeLen, sizeof(char*));
808                                             VERIFY_NON_NULL(TAG, rsrc->types, ERROR);
809
810                                             CborValue resourceTypes;
811                                             cborFindResult = cbor_value_enter_container(&rMap, &resourceTypes);
812                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering RT Array.");
813
814                                             for(size_t i = 0; cbor_value_is_valid(&resourceTypes) && cbor_value_is_text_string(&resourceTypes); i++)
815                                             {
816                                                 size_t readLen = 0;
817                                                 cborFindResult = cbor_value_dup_text_string(&resourceTypes, &(rsrc->types[i]), &readLen, NULL);
818                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding resource type.");
819                                                 cborFindResult = cbor_value_advance(&resourceTypes);
820                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing resource type.");
821                                             }
822                                         }
823
824                                         // "if"
825                                         if (0 == strcmp(OIC_JSON_IF_NAME, rMapName) && cbor_value_is_array(&rMap))
826                                         {
827                                             cbor_value_get_array_length(&rMap, &rsrc->interfaceLen);
828                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding IF array length.");
829                                             VERIFY_SUCCESS(TAG, (0 != rsrc->interfaceLen), ERROR);
830
831                                             rsrc->interfaces = (char**)OICCalloc(rsrc->interfaceLen, sizeof(char*));
832                                             VERIFY_NON_NULL(TAG, rsrc->interfaces, ERROR);
833
834                                             CborValue interfaces;
835                                             cborFindResult = cbor_value_enter_container(&rMap, &interfaces);
836                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering IF Array.");
837
838                                             for(size_t i = 0; cbor_value_is_valid(&interfaces) && cbor_value_is_text_string(&interfaces); i++)
839                                             {
840                                                 size_t readLen = 0;
841                                                 cborFindResult = cbor_value_dup_text_string(&interfaces, &(rsrc->interfaces[i]), &readLen, NULL);
842                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding IF type.");
843                                                 cborFindResult = cbor_value_advance(&interfaces);
844                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing IF type.");
845                                             }
846                                         }
847
848                                         // "rel"
849                                         if (0 == strcmp(OIC_JSON_REL_NAME, rMapName))
850                                         {
851                                             cborFindResult = cbor_value_dup_text_string(&rMap, &rsrc->rel, &len, NULL);
852                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding REL Value.");
853                                         }
854
855                                         if (cbor_value_is_valid(&rMap))
856                                         {
857                                             cborFindResult = cbor_value_advance(&rMap);
858                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Rlist Map.");
859                                         }
860                                         OICFree(rMapName);
861                                     }
862
863                                     if (cbor_value_is_valid(&resources))
864                                     {
865                                         cborFindResult = cbor_value_advance(&resources);
866                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Resource Array.");
867                                     }
868                                 }
869                             }
870
871                             // Permissions -- Mandatory
872                             if (strcmp(name, OIC_JSON_PERMISSION_NAME) == 0)
873                             {
874                                 uint64_t tmp64;
875                                 cborFindResult = cbor_value_get_uint64(&aceMap, &tmp64);
876                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a PERM Value.");
877                                 ace->permission = (uint16_t)tmp64;
878                             }
879
880                             // TODO: Need to verfication for validity
881                             // Validity -- Not mandatory
882                             if(strcmp(name, OIC_JSON_VALIDITY_NAME) == 0)
883                             {
884                                 CborValue validitiesMap = {.parser = NULL};
885                                 size_t validitySize = 0;
886
887                                 cborFindResult = cbor_value_get_array_length(&aceMap, &validitySize);
888                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a Validity Array Length.");
889
890                                 cborFindResult = cbor_value_enter_container(&aceMap, &validitiesMap);
891                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a validity Array Map.");
892
893                                 while(cbor_value_is_valid(&validitiesMap))
894                                 {
895                                     OicSecValidity_t* validity = (OicSecValidity_t*)OICCalloc(1, sizeof(OicSecValidity_t));
896                                     VERIFY_NON_NULL(TAG, validity, ERROR);
897                                     LL_APPEND(ace->validities, validity);
898
899                                     CborValue validityMap  = {.parser = NULL};
900                                     //period (string)
901                                     cborFindResult = cbor_value_enter_container(&validitiesMap, &validityMap);
902                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a validity Map.");
903
904                                     size_t len = 0;
905                                     cborFindResult =cbor_value_dup_text_string(&validityMap, &validity->period, &len, NULL);
906                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a Period value.");
907
908                                     //recurrence (string array)
909                                     CborValue recurrenceMap  = {.parser = NULL};
910                                     cborFindResult = cbor_value_enter_container(&validityMap, &recurrenceMap);
911                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a recurrence array.");
912
913                                     cborFindResult = cbor_value_get_array_length(&recurrenceMap, &validity->recurrenceLen);
914                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Adding Recurrence Array.");
915
916                                     validity->recurrences = (char**)OICCalloc(validity->recurrenceLen, sizeof(char*));
917                                     VERIFY_NON_NULL(TAG, validity->recurrences, ERROR);
918
919                                     for(size_t i = 0; cbor_value_is_text_string(&recurrenceMap) && i < validity->recurrenceLen; i++)
920                                     {
921                                         cborFindResult = cbor_value_dup_text_string(&recurrenceMap, &validity->recurrences[i], &len, NULL);
922                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a recurrence Value.");
923
924                                         cborFindResult = cbor_value_advance(&recurrenceMap);
925                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing a recurrences Array.");
926                                     }
927
928                                     cborFindResult = cbor_value_advance(&validitiesMap);
929                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing a validities Array.");
930                                 }
931                             }
932                             OICFree(name);
933                         }
934
935                         if (type != CborMapType && cbor_value_is_valid(&aceMap))
936                         {
937                             cborFindResult = cbor_value_advance(&aceMap);
938                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing the Array.");
939                         }
940                     }
941
942                     if (cbor_value_is_valid(&acesArray))
943                     {
944                         cborFindResult = cbor_value_advance(&acesArray);
945                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing ACL Array.");
946                     }
947                 }
948             }
949
950             //rownerID -- Mandatory
951             if (strcmp(tagName, OIC_JSON_ROWNERID_NAME)  == 0)
952             {
953                 char *stRowner = NULL;
954                 cborFindResult = cbor_value_dup_text_string(&aclMap, &stRowner, &len, NULL);
955                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Rownerid Value.");
956                 OIC_LOG_V(DEBUG, TAG, "Converting rownerid = %s to uuid...", stRowner);
957                 ret = ConvertStrToUuid(stRowner, &acl->rownerID);
958                 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
959                 OICFree(stRowner);
960             }
961             OICFree(tagName);
962         }
963         if (cbor_value_is_valid(&aclMap))
964         {
965             cborFindResult = cbor_value_advance(&aclMap);
966             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing ACL Map.");
967         }
968     }
969
970 exit:
971     if (cborFindResult != CborNoError)
972     {
973         OIC_LOG(ERROR, TAG, "Failed to CBORPayloadToAcl");
974         DeleteACLList(acl);
975         acl = NULL;
976     }
977
978     return acl;
979 }
980
981 // This function converts CBOR format to ACL data.
982 // Caller needs to invoke 'free' when done using
983 // note: This function is used in unit test hence not declared static,
984 OicSecAcl_t* CBORPayloadToAcl(const uint8_t *cborPayload, const size_t size)
985 {
986     if (NULL == cborPayload || 0 == size)
987     {
988         return NULL;
989     }
990     OCStackResult ret = OC_STACK_ERROR;
991     CborValue aclMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
992     CborValue aclCbor = { .parser = NULL };
993     CborParser parser = { .end = NULL };
994     CborError cborFindResult = CborNoError;
995
996     cbor_parser_init(cborPayload, size, 0, &parser, &aclCbor);
997
998     OicSecAcl_t *acl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
999     VERIFY_NON_NULL(TAG, acl, ERROR);
1000
1001     // Enter ACL Map
1002     cborFindResult = cbor_value_enter_container(&aclCbor, &aclMap);
1003     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACL Map.");
1004
1005     while (cbor_value_is_valid(&aclMap))
1006     {
1007         char* tagName = NULL;
1008         size_t len = 0;
1009         CborType type = cbor_value_get_type(&aclMap);
1010         if (type == CborTextStringType)
1011         {
1012             cborFindResult = cbor_value_dup_text_string(&aclMap, &tagName, &len, NULL);
1013             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in ACL Map.");
1014             cborFindResult = cbor_value_advance(&aclMap);
1015             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in ACL Map.");
1016         }
1017         if(tagName)
1018         {
1019             if (strcmp(tagName, OIC_JSON_ACLIST_NAME)  == 0)
1020             {
1021                 // Enter ACLIST Map
1022                 CborValue aclistMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
1023                 cborFindResult = cbor_value_enter_container(&aclMap, &aclistMap);
1024                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACLIST Map.");
1025
1026                 while (cbor_value_is_valid(&aclistMap))
1027                 {
1028                     char* acName = NULL;
1029                     size_t readLen = 0;
1030                     CborType acType = cbor_value_get_type(&aclistMap);
1031                     if (acType == CborTextStringType)
1032                     {
1033                         cborFindResult = cbor_value_dup_text_string(&aclistMap, &acName, &readLen, NULL);
1034                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in ACLIST Map.");
1035                         cborFindResult = cbor_value_advance(&aclistMap);
1036                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in ACLIST Map.");
1037                     }
1038
1039                     if(acName)
1040                     {
1041                         if (strcmp(acName, OIC_JSON_ACES_NAME)  == 0)
1042                         {
1043                             // Enter ACES Array
1044                             CborValue acesArray = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
1045                             cborFindResult = cbor_value_enter_container(&aclistMap, &acesArray);
1046                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACES Array.");
1047
1048                             int acesCount = 0;
1049                             while (cbor_value_is_valid(&acesArray))
1050                             {
1051                                 acesCount++;
1052                                 CborValue aceMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
1053                                 cborFindResult = cbor_value_enter_container(&acesArray, &aceMap);
1054                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACE Map.");
1055
1056                                 OicSecAce_t *ace = NULL;
1057                                 ace = (OicSecAce_t *) OICCalloc(1, sizeof(OicSecAce_t));
1058                                 VERIFY_NON_NULL(TAG, ace, ERROR);
1059                                 LL_APPEND(acl->aces, ace);
1060
1061                                 while (cbor_value_is_valid(&aceMap))
1062                                 {
1063                                     char* name = NULL;
1064                                     size_t len = 0;
1065                                     CborType type = cbor_value_get_type(&aceMap);
1066                                     if (type == CborTextStringType)
1067                                     {
1068                                         cborFindResult = cbor_value_dup_text_string(&aceMap, &name, &len, NULL);
1069                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in ACE Map.");
1070                                         cborFindResult = cbor_value_advance(&aceMap);
1071                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in ACE Map.");
1072                                     }
1073                                     if (name)
1074                                     {
1075                                         // Subject -- Mandatory
1076                                         if (strcmp(name, OIC_JSON_SUBJECTID_NAME)  == 0)
1077                                         {
1078                                             char *subject = NULL;
1079                                             cborFindResult = cbor_value_dup_text_string(&aceMap, &subject, &len, NULL);
1080                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding subject Value.");
1081                                             if(strcmp(subject, WILDCARD_RESOURCE_URI) == 0)
1082                                             {
1083                                                 ace->subjectuuid.id[0] = '*';
1084                                             }
1085                                             else
1086                                             {
1087                                                 ret = ConvertStrToUuid(subject, &ace->subjectuuid);
1088                                                 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
1089                                             }
1090                                             OICFree(subject);
1091                                         }
1092
1093                                         // Resources -- Mandatory
1094                                         if (strcmp(name, OIC_JSON_RESOURCES_NAME) == 0)
1095                                         {
1096                                             CborValue resources = { .parser = NULL };
1097                                             cborFindResult = cbor_value_enter_container(&aceMap, &resources);
1098                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering a Resource Array.");
1099
1100                                             while (cbor_value_is_valid(&resources))
1101                                             {
1102                                                 // rMap
1103                                                 CborValue rMap = { .parser = NULL  };
1104                                                 cborFindResult = cbor_value_enter_container(&resources, &rMap);
1105                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering Resource Map");
1106
1107                                                 OicSecRsrc_t* rsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1108                                                 VERIFY_NON_NULL(TAG, rsrc, ERROR);
1109                                                 LL_APPEND(ace->resources, rsrc);
1110
1111                                                 while(cbor_value_is_valid(&rMap))
1112                                                 {
1113                                                     char *rMapName = NULL;
1114                                                     size_t rMapNameLen = 0;
1115                                                     cborFindResult = cbor_value_dup_text_string(&rMap, &rMapName, &rMapNameLen, NULL);
1116                                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Name Tag.");
1117                                                     cborFindResult = cbor_value_advance(&rMap);
1118                                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Value.");
1119
1120                                                     // "href"
1121                                                     if (0 == strcmp(OIC_JSON_HREF_NAME, rMapName))
1122                                                     {
1123                                                         cborFindResult = cbor_value_dup_text_string(&rMap, &rsrc->href, &len, NULL);
1124                                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Href Value.");
1125                                                     }
1126
1127                                                     // "rt"
1128                                                     if (0 == strcmp(OIC_JSON_RT_NAME, rMapName) && cbor_value_is_array(&rMap))
1129                                                     {
1130                                                         cbor_value_get_array_length(&rMap, &rsrc->typeLen);
1131                                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RT array length.");
1132
1133                                                         CborValue resourceTypes;
1134
1135                                                         if (rsrc->typeLen == 0)
1136                                                         {
1137                                                             cborFindResult = cbor_value_enter_container(&rMap, &resourceTypes);
1138                                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering RT Array.");
1139
1140                                                             while (!cbor_value_at_end(&resourceTypes))
1141                                                             {
1142                                                                 rsrc->typeLen++;
1143                                                                 cborFindResult = cbor_value_advance(&resourceTypes);
1144                                                                 if (cborFindResult != CborNoError)
1145                                                                 {
1146                                                                     break;
1147                                                                 }
1148                                                             }
1149                                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RT array length.");
1150                                                         }
1151
1152                                                         VERIFY_SUCCESS(TAG, (0 != rsrc->typeLen), ERROR);
1153
1154                                                         rsrc->types = (char**)OICCalloc(rsrc->typeLen, sizeof(char*));
1155                                                         VERIFY_NON_NULL(TAG, rsrc->types, ERROR);
1156
1157                                                         cborFindResult = cbor_value_enter_container(&rMap, &resourceTypes);
1158                                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering RT Array.");
1159
1160                                                         for(size_t i = 0; cbor_value_is_valid(&resourceTypes) && cbor_value_is_text_string(&resourceTypes); i++)
1161                                                         {
1162                                                             cborFindResult = cbor_value_dup_text_string(&resourceTypes, &(rsrc->types[i]), &readLen, NULL);
1163                                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding resource type.");
1164                                                             cborFindResult = cbor_value_advance(&resourceTypes);
1165                                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing resource type.");
1166                                                         }
1167                                                     }
1168
1169                                                     // "if"
1170                                                     if (0 == strcmp(OIC_JSON_IF_NAME, rMapName) && cbor_value_is_array(&rMap))
1171                                                     {
1172                                                         cbor_value_get_array_length(&rMap, &rsrc->interfaceLen);
1173                                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding IF array length.");
1174
1175                                                         CborValue interfaces;
1176
1177                                                         if (rsrc->interfaceLen == 0)
1178                                                         {
1179                                                             cborFindResult = cbor_value_enter_container(&rMap, &interfaces);
1180                                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering IF Array.");
1181
1182                                                             while (!cbor_value_at_end(&interfaces))
1183                                                             {
1184                                                                 rsrc->interfaceLen++;
1185                                                                 cborFindResult = cbor_value_advance(&interfaces);
1186                                                                 if (cborFindResult != CborNoError)
1187                                                                 {
1188                                                                     break;
1189                                                                 }
1190                                                             }
1191                                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding IF array length.");
1192                                                         }
1193
1194                                                         VERIFY_SUCCESS(TAG, (0 != rsrc->interfaceLen), ERROR);
1195
1196                                                         rsrc->interfaces = (char**)OICCalloc(rsrc->interfaceLen, sizeof(char*));
1197                                                         VERIFY_NON_NULL(TAG, rsrc->interfaces, ERROR);
1198
1199                                                         cborFindResult = cbor_value_enter_container(&rMap, &interfaces);
1200                                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering IF Array.");
1201
1202                                                         for(size_t i = 0; cbor_value_is_valid(&interfaces) && cbor_value_is_text_string(&interfaces); i++)
1203                                                         {
1204                                                             cborFindResult = cbor_value_dup_text_string(&interfaces, &(rsrc->interfaces[i]), &readLen, NULL);
1205                                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding IF type.");
1206                                                             cborFindResult = cbor_value_advance(&interfaces);
1207                                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing IF type.");
1208                                                         }
1209                                                     }
1210
1211                                                     // "rel"
1212                                                     if (0 == strcmp(OIC_JSON_REL_NAME, rMapName))
1213                                                     {
1214                                                         cborFindResult = cbor_value_dup_text_string(&rMap, &rsrc->rel, &len, NULL);
1215                                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding REL Value.");
1216                                                     }
1217
1218                                                     if (cbor_value_is_valid(&rMap))
1219                                                     {
1220                                                         cborFindResult = cbor_value_advance(&rMap);
1221                                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Rlist Map.");
1222                                                     }
1223                                                     OICFree(rMapName);
1224                                                 }
1225
1226                                                 if (cbor_value_is_valid(&resources))
1227                                                 {
1228                                                     cborFindResult = cbor_value_advance(&resources);
1229                                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Resource Array.");
1230                                                 }
1231                                             }
1232                                         }
1233
1234                                         // Permissions -- Mandatory
1235                                         if (strcmp(name, OIC_JSON_PERMISSION_NAME) == 0)
1236                                         {
1237                                             uint64_t tmp64;
1238                                             cborFindResult = cbor_value_get_uint64(&aceMap, &tmp64);
1239                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a PERM Value.");
1240                                             ace->permission = (uint16_t)tmp64;
1241                                         }
1242
1243                                         // TODO: Need to verfication for validity
1244                                         // Validity -- Not mandatory
1245                                         if(strcmp(name, OIC_JSON_VALIDITY_NAME) == 0)
1246                                         {
1247                                             CborValue validitiesMap = {.parser = NULL};
1248                                             size_t validitySize = 0;
1249
1250                                             cborFindResult = cbor_value_get_array_length(&aceMap, &validitySize);
1251                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a Validity Array Length.");
1252
1253                                             cborFindResult = cbor_value_enter_container(&aceMap, &validitiesMap);
1254                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a validity Array Map.");
1255
1256                                             while(cbor_value_is_valid(&validitiesMap))
1257                                             {
1258                                                 OicSecValidity_t* validity = (OicSecValidity_t*)OICCalloc(1, sizeof(OicSecValidity_t));
1259                                                 VERIFY_NON_NULL(TAG, validity, ERROR);
1260                                                 LL_APPEND(ace->validities, validity);
1261
1262                                                 CborValue validityMap  = {.parser = NULL};
1263                                                 //period (string)
1264                                                 cborFindResult = cbor_value_enter_container(&validitiesMap, &validityMap);
1265                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a validity Map.");
1266
1267                                                 size_t len = 0;
1268                                                 cborFindResult =cbor_value_dup_text_string(&validityMap, &validity->period, &len, NULL);
1269                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a Period value.");
1270
1271                                                 //recurrence (string array)
1272                                                 CborValue recurrenceMap  = {.parser = NULL};
1273                                                 cborFindResult = cbor_value_enter_container(&validityMap, &recurrenceMap);
1274                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a recurrence array.");
1275
1276                                                 cborFindResult = cbor_value_get_array_length(&recurrenceMap, &validity->recurrenceLen);
1277                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Adding Recurrence Array.");
1278
1279                                                 validity->recurrences = (char**)OICCalloc(validity->recurrenceLen, sizeof(char*));
1280                                                 VERIFY_NON_NULL(TAG, validity->recurrences, ERROR);
1281
1282                                                 for(size_t i = 0; cbor_value_is_text_string(&recurrenceMap) && i < validity->recurrenceLen; i++)
1283                                                 {
1284                                                     cborFindResult = cbor_value_dup_text_string(&recurrenceMap, &validity->recurrences[i], &len, NULL);
1285                                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a recurrence Value.");
1286
1287                                                     cborFindResult = cbor_value_advance(&recurrenceMap);
1288                                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing a recurrences Array.");
1289                                                 }
1290
1291                                                 cborFindResult = cbor_value_advance(&validitiesMap);
1292                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing a validities Array.");
1293                                             }
1294                                         }
1295
1296 #ifdef MULTIPLE_OWNER
1297                                         // eowner uuid -- Not Mandatory
1298                                         if (strcmp(name, OIC_JSON_EOWNERID_NAME)  == 0)
1299                                         {
1300                                             char *eowner = NULL;
1301                                             cborFindResult = cbor_value_dup_text_string(&aceMap, &eowner, &len, NULL);
1302                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding eownerId Value.");
1303                                             if(NULL == ace->eownerID)
1304                                             {
1305                                                 ace->eownerID = (OicUuid_t*)OICCalloc(1, sizeof(OicUuid_t));
1306                                                 VERIFY_NON_NULL(TAG, ace->eownerID, ERROR);
1307                                             }
1308                                             ret = ConvertStrToUuid(eowner, ace->eownerID);
1309                                             OICFree(eowner);
1310                                             VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
1311                                         }
1312 #endif //MULTIPLE_OWNER
1313                                         OICFree(name);
1314                                     }
1315
1316                                     if (type != CborMapType && cbor_value_is_valid(&aceMap))
1317                                     {
1318                                         cborFindResult = cbor_value_advance(&aceMap);
1319                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing the Array.");
1320                                     }
1321                                 }
1322
1323                                 if (cbor_value_is_valid(&acesArray))
1324                                 {
1325                                     cborFindResult = cbor_value_advance(&acesArray);
1326                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing ACL Array.");
1327                                 }
1328                             }
1329                         }
1330                         OICFree(acName);
1331                     }
1332
1333                     if (cbor_value_is_valid(&aclistMap))
1334                     {
1335                         cborFindResult = cbor_value_advance(&aclistMap);
1336                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing ACLIST Map.");
1337                     }
1338                 }
1339             }
1340
1341             //rownerID -- Mandatory
1342             if (strcmp(tagName, OIC_JSON_ROWNERID_NAME)  == 0)
1343             {
1344                 char *stRowner = NULL;
1345                 cborFindResult = cbor_value_dup_text_string(&aclMap, &stRowner, &len, NULL);
1346                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Rownerid Value.");
1347                 ret = ConvertStrToUuid(stRowner, &acl->rownerID);
1348                 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
1349                 OICFree(stRowner);
1350             }
1351             else if (NULL != gAcl)
1352             {
1353                 memcpy(&(acl->rownerID), &(gAcl->rownerID), sizeof(OicUuid_t));
1354             }
1355             OICFree(tagName);
1356         }
1357         if (cbor_value_is_valid(&aclMap))
1358         {
1359             cborFindResult = cbor_value_advance(&aclMap);
1360             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing ACL Map.");
1361         }
1362     }
1363
1364 exit:
1365     if (cborFindResult != CborNoError)
1366     {
1367         OIC_LOG(ERROR, TAG, "Failed to CBORPayloadToAcl");
1368         DeleteACLList(acl);
1369         acl = NULL;
1370     }
1371
1372     return acl;
1373 }
1374
1375 #ifdef MULTIPLE_OWNER
1376 bool IsValidAclAccessForSubOwner(const OicUuid_t* uuid, const uint8_t *cborPayload, const size_t size)
1377 {
1378     bool retValue = false;
1379     OicSecAcl_t* acl = NULL;
1380
1381     VERIFY_NON_NULL(TAG, uuid, ERROR);
1382     VERIFY_NON_NULL(TAG, cborPayload, ERROR);
1383     VERIFY_SUCCESS(TAG, 0 != size, ERROR);
1384
1385     acl = CBORPayloadToAcl(cborPayload, size);
1386     VERIFY_NON_NULL(TAG, acl, ERROR);
1387
1388     OicSecAce_t* ace = NULL;
1389     OicSecAce_t* tempAce = NULL;
1390     LL_FOREACH_SAFE(acl->aces, ace, tempAce)
1391     {
1392         OicSecRsrc_t* rsrc = NULL;
1393         OicSecRsrc_t* tempRsrc = NULL;
1394
1395         VERIFY_NON_NULL(TAG, ace->eownerID, ERROR);
1396         VERIFY_SUCCESS(TAG, memcmp(ace->eownerID->id, uuid->id, sizeof(uuid->id)) == 0, ERROR);
1397
1398         LL_FOREACH_SAFE(ace->resources, rsrc, tempRsrc)
1399         {
1400             VERIFY_SUCCESS(TAG, strcmp(rsrc->href, OIC_RSRC_TYPE_SEC_DOXM) != 0, ERROR);
1401             VERIFY_SUCCESS(TAG, strcmp(rsrc->href, OIC_RSRC_TYPE_SEC_CRED) != 0, ERROR);
1402             VERIFY_SUCCESS(TAG, strcmp(rsrc->href, OIC_RSRC_TYPE_SEC_ACL) != 0, ERROR);
1403             VERIFY_SUCCESS(TAG, strcmp(rsrc->href, OIC_RSRC_TYPE_SEC_PSTAT) != 0, ERROR);
1404             VERIFY_SUCCESS(TAG, strcmp(rsrc->href, OIC_RSRC_TYPE_SEC_CRL) != 0, ERROR);
1405         }
1406     }
1407
1408     retValue = true;
1409
1410 exit:
1411     DeleteACLList(acl);
1412
1413     return retValue;
1414 }
1415 #endif //MULTIPLE_OWNER
1416
1417 /**
1418  * This method removes ACE for the subject and resource from the ACL
1419  *
1420  * @param subject of the ACE
1421  * @param resource of the ACE
1422  *
1423  * @return
1424  *     ::OC_STACK_RESOURCE_DELETED on success
1425  *     ::OC_STACK_NO_RESOURCE on failure to find the appropriate ACE
1426  *     ::OC_STACK_INVALID_PARAM on invalid parameter
1427  */
1428 OCStackResult RemoveACE(const OicUuid_t * subject, const char * resource)
1429 {
1430     OIC_LOG(DEBUG, TAG, "IN RemoveACE");
1431
1432     if (!gAcl)
1433     {
1434         OIC_LOG_V(ERROR, TAG, "%s: gAcl is NULL", __func__);
1435         return OC_STACK_INVALID_PARAM;
1436     }
1437
1438     OicSecAce_t *ace = NULL;
1439     OicSecAce_t *tempAce = NULL;
1440     bool deleteFlag = false;
1441     OCStackResult ret = OC_STACK_NO_RESOURCE;
1442
1443     if (memcmp(subject->id, &WILDCARD_SUBJECT_ID, sizeof(subject->id)) == 0)
1444     {
1445         OIC_LOG_V(ERROR, TAG, "%s received invalid parameter", __func__ );
1446         return  OC_STACK_INVALID_PARAM;
1447     }
1448
1449     //If resource is NULL then delete all the ACE for the subject.
1450     if (NULL == resource || resource[0] == '\0')
1451     {
1452         LL_FOREACH_SAFE(gAcl->aces, ace, tempAce)
1453         {
1454             if (memcmp(ace->subjectuuid.id, subject->id, sizeof(subject->id)) == 0)
1455             {
1456                 LL_DELETE(gAcl->aces, ace);
1457                 FreeACE(ace);
1458                 deleteFlag = true;
1459             }
1460         }
1461     }
1462     else
1463     {
1464         //Looping through ACL to find the right ACE to delete. If the required resource is the only
1465         //resource in the ACE for the subject then delete the whole ACE. If there are more resources
1466         //than the required resource in the ACE, for the subject then just delete the resource from
1467         //the resource array
1468         LL_FOREACH_SAFE(gAcl->aces, ace, tempAce)
1469         {
1470             if (memcmp(ace->subjectuuid.id, subject->id, sizeof(subject->id)) == 0)
1471             {
1472                 OicSecRsrc_t* rsrc = NULL;
1473                 OicSecRsrc_t* tempRsrc = NULL;
1474                 LL_FOREACH_SAFE(ace->resources, rsrc, tempRsrc)
1475                 {
1476                     if(strcmp(rsrc->href, resource) == 0)
1477                     {
1478                         LL_DELETE(ace->resources, rsrc);
1479                         FreeRsrc(rsrc);
1480                         deleteFlag = true;
1481                     }
1482                 }
1483
1484                 //If resource list is empty
1485                 if(NULL == ace->resources && true == deleteFlag)
1486                 {
1487                     //Remove the ACE from ACL
1488                     LL_DELETE(gAcl->aces, ace);
1489                     FreeACE(ace);
1490                 }
1491             }
1492         }
1493     }
1494
1495     if (deleteFlag)
1496     {
1497         // In case of unit test do not update persistant storage.
1498         if (memcmp(subject->id, &WILDCARD_SUBJECT_B64_ID, sizeof(subject->id)) == 0)
1499         {
1500             ret = OC_STACK_RESOURCE_DELETED;
1501         }
1502         else
1503         {
1504             uint8_t *payload = NULL;
1505             size_t size = 0;
1506             if (OC_STACK_OK == AclToCBORPayload(gAcl, &payload, &size))
1507             {
1508                 if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, payload, size))
1509                 {
1510                     ret = OC_STACK_RESOURCE_DELETED;
1511                 }
1512                 OICFree(payload);
1513             }
1514         }
1515     }
1516     return ret;
1517 }
1518
1519 /**
1520  * This method parses the query string received for REST requests and
1521  * retrieves the 'subject' field.
1522  *
1523  * @param query querystring passed in REST request
1524  * @param subject subject UUID parsed from query string
1525  *
1526  * @return true if query parsed successfully and found 'subject', else false.
1527  */
1528 static bool GetSubjectFromQueryString(const char *query, OicUuid_t *subject)
1529 {
1530     OicParseQueryIter_t parseIter = { .attrPos = NULL };
1531
1532     ParseQueryIterInit((unsigned char *) query, &parseIter);
1533
1534     while (GetNextQuery (&parseIter))
1535     {
1536         if (strncasecmp((char *) parseIter.attrPos, OIC_JSON_SUBJECTID_NAME, parseIter.attrLen) == 0)
1537         {
1538             char strUuid[STRING_UUID_SIZE] = {0};
1539             VERIFY_SUCCESS(TAG, 0 != parseIter.valLen, ERROR);
1540             memcpy(strUuid, parseIter.valPos, parseIter.valLen);
1541             OCStackResult res = ConvertStrToUuid(strUuid, subject);
1542             VERIFY_SUCCESS(TAG, OC_STACK_OK == res, ERROR);
1543             return true;
1544         }
1545     }
1546
1547 exit:
1548     return false;
1549 }
1550
1551 /**
1552  * This method parses the query string received for REST requests and
1553  * retrieves the 'resource' field.
1554  *
1555  * @param query querystring passed in REST request
1556  * @param resource resource parsed from query string
1557  * @param resourceSize size of the memory pointed to resource
1558  *
1559  * @return true if query parsed successfully and found 'resource', else false.
1560  */
1561 static bool GetResourceFromQueryString(const char *query, char *resource, size_t resourceSize)
1562 {
1563     OicParseQueryIter_t parseIter = { .attrPos = NULL };
1564
1565     ParseQueryIterInit((unsigned char *) query, &parseIter);
1566
1567     while (GetNextQuery (&parseIter))
1568     {
1569         if (strncasecmp((char *) parseIter.attrPos, OIC_JSON_RESOURCES_NAME, parseIter.attrLen)
1570                 == 0)
1571         {
1572             VERIFY_SUCCESS(TAG, 0 != parseIter.valLen, ERROR);
1573             OICStrcpy(resource, resourceSize, (char *) parseIter.valPos);
1574
1575             return true;
1576         }
1577     }
1578
1579 exit:
1580    return false;
1581 }
1582
1583 static size_t GetNumberOfResource(OicSecRsrc_t* resources)
1584 {
1585     size_t ret = 0;
1586     if(resources)
1587     {
1588         OicSecRsrc_t* rsrc = NULL;
1589         LL_FOREACH(resources, rsrc)
1590         {
1591             ret++;
1592         }
1593     }
1594     return ret;
1595 }
1596
1597 static size_t GetNumberOfValidity(OicSecValidity_t* val)
1598 {
1599     size_t ret = 0;
1600
1601     if(val)
1602     {
1603         OicSecValidity_t* temp = NULL;
1604         LL_FOREACH(val, temp)
1605         {
1606             ret++;
1607         }
1608     }
1609     return ret;
1610 }
1611
1612
1613 static bool IsSameStringArray(char** strArr1, size_t strArr1Len,
1614                               char** strArr2, size_t strArr2Len)
1615 {
1616
1617     if(NULL == strArr1 && NULL == strArr2)
1618     {
1619         return true;
1620     }
1621
1622     if(strArr1 && strArr2 && NULL == *strArr1 && NULL == *strArr2)
1623     {
1624         return true;
1625     }
1626
1627     if(strArr1 && strArr2)
1628     {
1629         if(*strArr1 && *strArr2 && strArr1Len == strArr2Len)
1630         {
1631             size_t matchedStr = 0;
1632             for(size_t i = 0; i < strArr1Len; i++)
1633             {
1634                 for(size_t j = 0; j < strArr2Len; j++)
1635                 {
1636                     if(strcmp(strArr1[i], strArr2[j]) == 0)
1637                     {
1638                         matchedStr++;
1639                     }
1640                 }
1641             }
1642             if(matchedStr == strArr1Len)
1643             {
1644                 return true;
1645             }
1646         }
1647     }
1648
1649     return false;
1650 }
1651
1652 static bool IsSameResources(OicSecRsrc_t* resources1, OicSecRsrc_t* resources2)
1653 {
1654     size_t numOfRsrc1 = 0;
1655     size_t numOfRsrc2 = 0;
1656     size_t numOfMatchedRsrc = 0;
1657     OicSecRsrc_t* rsrc1 = NULL;
1658     OicSecRsrc_t* rsrc2 = NULL;
1659
1660     if(NULL == resources1 && NULL == resources2)
1661     {
1662         return true;
1663     }
1664
1665     if(resources1 && resources2)
1666     {
1667         numOfRsrc1 = GetNumberOfResource(resources1);
1668         numOfRsrc2 = GetNumberOfResource(resources2);
1669
1670         if(0 == numOfRsrc1 && 0 == numOfRsrc2)
1671         {
1672             return true;
1673         }
1674
1675         LL_FOREACH(resources1, rsrc1)
1676         {
1677             rsrc2 = NULL;
1678             LL_FOREACH(resources2, rsrc2)
1679             {
1680                 if(rsrc1 && rsrc2)
1681                 {
1682                     if(strcmp(rsrc1->href, rsrc2->href) == 0 &&
1683                         IsSameStringArray(rsrc1->interfaces, rsrc1->interfaceLen,
1684                                           rsrc2->interfaces, rsrc2->interfaceLen) &&
1685                         IsSameStringArray(rsrc1->types, rsrc1->typeLen,
1686                                           rsrc2->types, rsrc2->typeLen))
1687                     {
1688                         // TODO: Update codes to compare 'rel' property
1689                         numOfMatchedRsrc++;
1690                     }
1691                 }
1692             }
1693         }
1694
1695         if(numOfMatchedRsrc == numOfRsrc1)
1696         {
1697             return true;
1698         }
1699     }
1700
1701     return false;
1702 }
1703
1704 static bool IsSameValidities(OicSecValidity_t* validities1, OicSecValidity_t* validities2)
1705 {
1706     size_t numOfVal1 = 0;
1707     size_t numOfVal2 = 0;
1708     size_t numOfMatchedVal = 0;
1709     OicSecValidity_t* val1 = NULL;
1710     OicSecValidity_t* val2 = NULL;
1711
1712     if(NULL == validities1 && NULL == validities2)
1713     {
1714         return true;
1715     }
1716
1717     if(validities1 && validities2)
1718     {
1719         numOfVal1 = GetNumberOfValidity(validities1);
1720         numOfVal2 = GetNumberOfValidity(validities2);
1721         if(0 == numOfVal1 && 0 == numOfVal2)
1722         {
1723             return true;
1724         }
1725
1726         if(numOfVal1 == numOfVal2)
1727         {
1728             LL_FOREACH(validities1, val1)
1729             {
1730                 LL_FOREACH(validities2, val2)
1731                 {
1732                     if(strcmp(val1->period, val2->period) == 0 &&
1733                         IsSameStringArray(val1->recurrences, val1->recurrenceLen,
1734                                           val2->recurrences, val2->recurrenceLen))
1735                     {
1736                         numOfMatchedVal++;
1737                     }
1738                 }
1739             }
1740             if(numOfVal1 == numOfMatchedVal)
1741             {
1742                 return true;
1743             }
1744         }
1745     }
1746
1747     return false;
1748 }
1749
1750 #ifdef MULTIPLE_OWNER
1751 static bool IsSameEowner(OicUuid_t* eowner1, OicUuid_t* eowner2)
1752 {
1753     if (NULL != eowner1 && NULL != eowner2)
1754     {
1755         if (memcmp(eowner1->id, eowner2->id, sizeof(eowner1->id)) == 0)
1756         {
1757             return true;
1758         }
1759     }
1760     else if (NULL == eowner1 && NULL == eowner2)
1761     {
1762         OIC_LOG(DEBUG, TAG, "Both eowner1 and eowner2 are NULL");
1763         return true;
1764     }
1765
1766     return false;
1767 }
1768 #endif
1769
1770 static bool IsSameACE(OicSecAce_t* ace1, OicSecAce_t* ace2)
1771 {
1772     if(ace1 && ace2)
1773     {
1774         if(memcmp(ace1->subjectuuid.id, ace2->subjectuuid.id, sizeof(ace1->subjectuuid.id)) != 0)
1775         {
1776             return false;
1777         }
1778
1779         if(false == IsSameResources(ace1->resources, ace2->resources))
1780         {
1781             return false;
1782         }
1783
1784         if(ace1->permission != ace2->permission)
1785         {
1786             return false;
1787         }
1788
1789         if(false == IsSameValidities(ace1->validities, ace2->validities))
1790         {
1791             return false;
1792         }
1793
1794 #ifdef MULTIPLE_OWNER
1795         if(false == IsSameEowner(ace1->eownerID, ace2->eownerID))
1796         {
1797             return false;
1798         }
1799 #endif
1800
1801         return true;
1802     }
1803
1804     return false;
1805 }
1806
1807 /**
1808  * Internal function to remove all ACL data on ACL resource and persistent storage
1809  *
1810  * @retval
1811  *     OC_STACK_RESOURCE_DELETED  - no errors
1812  *     Otherwise                  - error
1813  */
1814 static OCStackResult RemoveAllAce(void)
1815 {
1816     OCStackResult ret = OC_STACK_ERROR;
1817     uint8_t* aclBackup = NULL;
1818     size_t backupSize = 0;
1819     uint8_t* payload = NULL;
1820     size_t size = 0;
1821     OicSecAce_t* aceItem = NULL;
1822     OicSecAce_t* tempAce = NULL;
1823
1824     OIC_LOG(INFO, TAG, "IN RemoveAllAce");
1825
1826     //Backup the current ACL
1827     ret = AclToCBORPayload(gAcl, &aclBackup, &backupSize);
1828     if(OC_STACK_OK == ret)
1829     {
1830         // Remove all ACE from ACL
1831         LL_FOREACH_SAFE(gAcl->aces, aceItem, tempAce)
1832         {
1833             LL_DELETE(gAcl->aces, aceItem);
1834             FreeACE(aceItem);
1835         }
1836
1837         //Generate empty ACL payload
1838         ret = AclToCBORPayload(gAcl, &payload, &size);
1839         if (OC_STACK_OK == ret )
1840         {
1841             //Update the PS.
1842             ret = UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, payload, size);
1843             if (OC_STACK_OK != ret)
1844             {
1845                 OIC_LOG_V(ERROR, TAG, "Error in UpdateSecureResourceInPS : %d", ret);
1846             }
1847         }
1848
1849         if(OC_STACK_OK != ret)
1850         {
1851             OIC_LOG_V(ERROR, TAG, "Error while DELETE ACE : %d", ret);
1852
1853             //If some erorr is occured, revert back.
1854             OicSecAcl_t* originAcl = CBORPayloadToAcl(aclBackup, backupSize);
1855             if( originAcl )
1856             {
1857                 ret = UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, aclBackup, backupSize);
1858                 if (OC_STACK_OK == ret)
1859                 {
1860                     DeleteACLList(gAcl);
1861                     gAcl = originAcl;
1862                 }
1863                 else
1864                 {
1865                     OIC_LOG_V(ERROR, TAG, "Error in UpdateSecureResourceInPS : %d", ret);
1866                 }
1867             }
1868             else
1869             {
1870                 OIC_LOG(FATAL, TAG, "Error in CBORPayloadToAcl");
1871                 ret = OC_STACK_ERROR;
1872             }
1873         }
1874     }
1875
1876     OICFree(aclBackup);
1877     OICFree(payload);
1878
1879     OIC_LOG(INFO, TAG, "OUT RemoveAllAce");
1880
1881     return (OC_STACK_OK == ret ? OC_STACK_RESOURCE_DELETED : ret);
1882 }
1883
1884 static OCEntityHandlerResult HandleACLGetRequest(const OCEntityHandlerRequest *ehRequest)
1885 {
1886     OIC_LOG(INFO, TAG, "HandleACLGetRequest processing the request");
1887
1888     uint8_t* payload = NULL;
1889     size_t size = 0;
1890     OCEntityHandlerResult ehRet;
1891
1892     OicUuid_t subject = {.id= { 0 } };
1893
1894     // In case, 'subject' field is included in REST request.
1895     if (ehRequest->query && GetSubjectFromQueryString(ehRequest->query, &subject))
1896     {
1897         OIC_LOG(DEBUG,TAG,"'subject' field is inculded in REST request.");
1898         OIC_LOG(DEBUG, TAG, "HandleACLGetRequest processing query");
1899
1900         char resource[MAX_URI_LENGTH] = { 0 };
1901
1902         OicSecAce_t *savePtr = NULL;
1903         const OicSecAce_t *currentAce = NULL;
1904         OicSecAcl_t targetAcl;
1905
1906         if (NULL != gAcl)
1907         {
1908             memcpy(&targetAcl.rownerID, &gAcl->rownerID, sizeof(OicUuid_t));
1909         }
1910         else
1911         {
1912             OIC_LOG_V(ERROR, TAG, "%s: gAcl is NULL", __func__);
1913             goto exit;
1914         }
1915
1916         targetAcl.aces = NULL;
1917
1918         // 'Subject' field is MUST for processing a querystring in REST request.
1919         GetResourceFromQueryString(ehRequest->query, resource, sizeof(resource));
1920
1921         /*
1922          * TODO : Currently, this code only provides one ACE for a Subject.
1923          * Below code needs to be updated for scenarios when Subject have
1924          * multiple ACE's in ACL resource.
1925          */
1926         while ((currentAce = GetACLResourceData(&subject, &savePtr)))
1927         {
1928             targetAcl.aces = (OicSecAce_t*)currentAce;
1929
1930             /*
1931              * If REST querystring contains a specific resource, we need
1932              * to search for that resource in ACE.
1933              */
1934             if (resource[0] != '\0')
1935             {
1936                 OicSecRsrc_t *rsrc = NULL;
1937                 LL_FOREACH(currentAce->resources, rsrc)
1938                 {
1939                     if(0 == strcmp(rsrc->href, resource) ||
1940                         0 == strcmp(WILDCARD_RESOURCE_URI, rsrc->href))
1941                     {
1942                         // Convert ACL data into CBOR format for transmission
1943                         if (OC_STACK_OK != AclToCBORPayload(&targetAcl, &payload, &size))
1944                         {
1945                             ehRet = OC_EH_ERROR;
1946                         }
1947                         goto exit;
1948                     }
1949                 }
1950             }
1951             else
1952             {
1953                 // Convert ACL data into CBOR format for transmission
1954                 if (OC_STACK_OK != AclToCBORPayload(&targetAcl, &payload, &size))
1955                 {
1956                     ehRet = OC_EH_ERROR;
1957                 }
1958                 goto exit;
1959             }
1960         }
1961     }
1962     // In case, 'subject' field is not included in REST request.
1963     else
1964     {
1965         OIC_LOG(DEBUG,TAG,"'subject' field is not inculded in REST request.");
1966         // Convert ACL data into CBOR format for transmission.
1967         if (OC_STACK_OK != AclToCBORPayload(gAcl, &payload, &size))
1968         {
1969             ehRet = OC_EH_ERROR;
1970         }
1971     }
1972 exit:
1973     // A device should always have a default acl. Therefore, payload should never be NULL.
1974     ehRet = (payload ? OC_EH_OK : OC_EH_ERROR);
1975     OIC_LOG(DEBUG, TAG, "ACL payload with GET response");
1976     OIC_LOG_BUFFER(DEBUG, TAG, payload, size);
1977
1978     //Send payload to request originator
1979     ehRet = ((SendSRMResponse(ehRequest, ehRet, payload, size)) == OC_STACK_OK) ?
1980                    OC_EH_OK : OC_EH_ERROR;
1981
1982     OICFree(payload);
1983
1984     OIC_LOG_V(DEBUG, TAG, "%s RetVal %d", __func__, ehRet);
1985     return ehRet;
1986 }
1987
1988 static OCEntityHandlerResult HandleACLPostRequest(const OCEntityHandlerRequest *ehRequest)
1989 {
1990     OIC_LOG(INFO, TAG, "HandleACLPostRequest processing the request");
1991     OCEntityHandlerResult ehRet = OC_EH_OK;
1992
1993     // Convert CBOR into ACL data and update to SVR buffers. This will also validate the ACL data received.
1994     uint8_t *payload = ((OCSecurityPayload *) ehRequest->payload)->securityData;
1995     size_t size = ((OCSecurityPayload *) ehRequest->payload)->payloadSize;
1996     if (payload)
1997     {
1998         OicSecAcl_t *newAcl = NULL;
1999         OIC_LOG(DEBUG, TAG, "ACL payload from POST request << ");
2000         OIC_LOG_BUFFER(DEBUG, TAG, payload, size);
2001
2002         newAcl = CBORPayloadToAcl(payload, size);
2003         if (NULL != newAcl && NULL != gAcl)
2004         {
2005             bool isNewAce = true;
2006             OicSecAce_t* existAce = NULL;
2007             OicSecAce_t* newAce = NULL;
2008             OicSecAce_t* tempAce1 = NULL;
2009             OicSecAce_t* tempAce2 = NULL;
2010
2011             LL_FOREACH_SAFE(newAcl->aces, newAce, tempAce1)
2012             {
2013                 isNewAce = true;
2014                 LL_FOREACH_SAFE(gAcl->aces, existAce, tempAce2)
2015                 {
2016                     if(IsSameACE(newAce, existAce))
2017                     {
2018                         isNewAce = false;
2019                     }
2020                 }
2021                 if(isNewAce)
2022                 {
2023                     OIC_LOG(DEBUG, TAG, "NEW ACE dectected.");
2024
2025                     OicSecAce_t* insertAce = DuplicateACE(newAce);
2026                     if(insertAce)
2027                     {
2028                         OIC_LOG(DEBUG, TAG, "Appending new ACE..");
2029                         LL_PREPEND(gAcl->aces, insertAce);
2030                     }
2031                     else
2032                     {
2033                         OIC_LOG(ERROR, TAG, "Failed to duplicate ACE.");
2034                         ehRet = OC_EH_ERROR;
2035                     }
2036                 }
2037             }
2038             memcpy(&(gAcl->rownerID), &(newAcl->rownerID), sizeof(OicUuid_t));
2039
2040             DeleteACLList(newAcl);
2041
2042             if(OC_EH_OK == ehRet)
2043             {
2044                 size_t size = 0;
2045                 uint8_t *cborPayload = NULL;
2046
2047                 if (OC_STACK_OK == AclToCBORPayload(gAcl, &cborPayload, &size))
2048                 {
2049                     if (UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, cborPayload, size) == OC_STACK_OK)
2050                     {
2051                         ehRet = OC_EH_CHANGED;
2052                     }
2053                     OICFree(cborPayload);
2054                 }
2055
2056                 if(OC_EH_CHANGED != ehRet)
2057                 {
2058                     ehRet = OC_EH_ERROR;
2059                 }
2060             }
2061         }
2062         else
2063         {
2064             OIC_LOG_V(ERROR, TAG, "%s: %s", __func__, (NULL == newAcl) ? "no new ACL" : "gAcl is NULL");
2065         }
2066     }
2067
2068     //Send response to request originator
2069     ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
2070                    OC_EH_OK : OC_EH_ERROR;
2071
2072     OIC_LOG_V(DEBUG, TAG, "%s RetVal %d", __func__, ehRet);
2073     return ehRet;
2074 }
2075
2076 static OCEntityHandlerResult HandleACLDeleteRequest(const OCEntityHandlerRequest *ehRequest)
2077 {
2078     OIC_LOG(DEBUG, TAG, "Processing ACLDeleteRequest");
2079     OCEntityHandlerResult ehRet = OC_EH_ERROR;
2080     OicUuid_t subject = { .id= { 0 } };
2081     char resource[MAX_URI_LENGTH] = { 0 };
2082
2083     VERIFY_NON_NULL(TAG, ehRequest->query, ERROR);
2084
2085     // If 'Subject' field exist, processing a querystring in REST request.
2086     if(GetSubjectFromQueryString(ehRequest->query, &subject))
2087     {
2088         GetResourceFromQueryString(ehRequest->query, resource, sizeof(resource));
2089
2090         if (OC_STACK_RESOURCE_DELETED == RemoveACE(&subject, resource))
2091         {
2092             ehRet = OC_EH_RESOURCE_DELETED;
2093         }
2094     }
2095     // If 'subject field not exist, remove all ACL data from ACL resource
2096     else
2097     {
2098         OIC_LOG(WARNING, TAG, "Can not find the 'subject' in querystring, All ACL list will be removed.");
2099
2100         if(OC_STACK_RESOURCE_DELETED == RemoveAllAce())
2101         {
2102             ehRet = OC_EH_RESOURCE_DELETED;
2103         }
2104     }
2105
2106 exit:
2107     //Send response to request originator
2108     ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
2109                    OC_EH_OK : OC_EH_ERROR;
2110
2111     return ehRet;
2112 }
2113
2114 OCEntityHandlerResult ACLEntityHandler(OCEntityHandlerFlag flag, OCEntityHandlerRequest * ehRequest,
2115         void* callbackParameter)
2116 {
2117     OIC_LOG(DEBUG, TAG, "Received request ACLEntityHandler");
2118     (void)callbackParameter;
2119     OCEntityHandlerResult ehRet = OC_EH_ERROR;
2120
2121     if (!ehRequest)
2122     {
2123         return ehRet;
2124     }
2125
2126     if (flag & OC_REQUEST_FLAG)
2127     {
2128         // TODO :  Handle PUT method
2129         OIC_LOG(DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
2130         switch (ehRequest->method)
2131         {
2132             case OC_REST_GET:
2133                 ehRet = HandleACLGetRequest(ehRequest);
2134                 break;
2135
2136             case OC_REST_POST:
2137                 ehRet = HandleACLPostRequest(ehRequest);
2138                 break;
2139
2140             case OC_REST_DELETE:
2141                 ehRet = HandleACLDeleteRequest(ehRequest);
2142                 break;
2143
2144             default:
2145                 ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
2146                                OC_EH_OK : OC_EH_ERROR;
2147         }
2148     }
2149
2150     return ehRet;
2151 }
2152
2153 /**
2154  * This internal method is used to create '/oic/sec/acl' resource.
2155  */
2156 static OCStackResult CreateACLResource()
2157 {
2158     OCStackResult ret;
2159
2160     ret = OCCreateResource(&gAclHandle,
2161                            OIC_RSRC_TYPE_SEC_ACL,
2162                            OC_RSRVD_INTERFACE_DEFAULT,
2163                            OIC_RSRC_ACL_URI,
2164                            ACLEntityHandler,
2165                            NULL,
2166                            OC_SECURE);
2167
2168     if (OC_STACK_OK != ret)
2169     {
2170         OIC_LOG(FATAL, TAG, "Unable to instantiate ACL resource");
2171         DeInitACLResource();
2172     }
2173     return ret;
2174 }
2175
2176 // This function sets the default ACL and is defined for the unit test only.
2177 OCStackResult SetDefaultACL(OicSecAcl_t *acl)
2178 {
2179     gAcl = acl;
2180     return OC_STACK_OK;
2181 }
2182
2183 OCStackResult GetDefaultACL(OicSecAcl_t** defaultAcl)
2184 {
2185     OCStackResult ret = OC_STACK_ERROR;
2186     OicUuid_t ownerId = { .id = { 0 } };
2187     OicSecAcl_t *acl = NULL;
2188     OicSecAce_t *ace = NULL;
2189     OicSecRsrc_t* resRsrc = NULL;
2190     OicSecRsrc_t* deviceRsrc = NULL;
2191     OicSecRsrc_t* platformRsrc = NULL;
2192     OicSecRsrc_t* aclRsrc = NULL;
2193     OicSecRsrc_t* doxmRsrc = NULL;
2194     OicSecRsrc_t* pstatRsrc = NULL;
2195
2196     /*
2197      * TODO In future, when new virtual resources will be added in OIC
2198      * specification, Iotivity stack should be able to add them in
2199      * existing SVR database. To support this, we need to add 'versioning'
2200      * mechanism in SVR database.
2201      */
2202
2203     if (!defaultAcl)
2204     {
2205         return OC_STACK_INVALID_PARAM;
2206     }
2207
2208     acl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
2209     VERIFY_NON_NULL(TAG, acl, ERROR);
2210
2211     ace = (OicSecAce_t *) OICCalloc(1, sizeof(OicSecAce_t));
2212     VERIFY_NON_NULL(TAG, ace, ERROR);
2213
2214     LL_APPEND(acl->aces, ace);
2215
2216     // Subject -- Mandatory
2217     memcpy(ace->subjectuuid.id, &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t));
2218
2219     // Resources -- Mandatory
2220     // /oic/res
2221     resRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
2222     VERIFY_NON_NULL(TAG, resRsrc, ERROR);
2223     LL_APPEND(ace->resources, resRsrc);
2224     resRsrc->href = OICStrdup(OC_RSRVD_WELL_KNOWN_URI);
2225     VERIFY_NON_NULL(TAG, (resRsrc->href), ERROR);
2226     resRsrc->typeLen = 1;
2227     resRsrc->types = (char**)OICCalloc(1, sizeof(char*));
2228     VERIFY_NON_NULL(TAG, resRsrc->types, ERROR);
2229     resRsrc->types[0] = OICStrdup(OC_RSRVD_RESOURCE_TYPE_RES);
2230     VERIFY_NON_NULL(TAG, resRsrc->types[0], ERROR);
2231     resRsrc->interfaceLen = 2;
2232     resRsrc->interfaces = (char**)OICCalloc(resRsrc->interfaceLen, sizeof(char*));
2233     VERIFY_NON_NULL(TAG, resRsrc->interfaces, ERROR);
2234     resRsrc->interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
2235     VERIFY_NON_NULL(TAG, resRsrc->interfaces[0], ERROR);
2236     resRsrc->interfaces[1] = OICStrdup(OC_RSRVD_INTERFACE_READ);
2237     VERIFY_NON_NULL(TAG, resRsrc->interfaces[1], ERROR);
2238
2239     // /oic/d
2240     deviceRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
2241     VERIFY_NON_NULL(TAG, deviceRsrc, ERROR);
2242     LL_APPEND(ace->resources, deviceRsrc);
2243     deviceRsrc->href = OICStrdup(OC_RSRVD_DEVICE_URI);
2244     VERIFY_NON_NULL(TAG, (deviceRsrc->href), ERROR);
2245     deviceRsrc->typeLen = 1;
2246     deviceRsrc->types = (char**)OICCalloc(1, sizeof(char*));
2247     VERIFY_NON_NULL(TAG, deviceRsrc->types, ERROR);
2248     deviceRsrc->types[0] = OICStrdup(OC_RSRVD_RESOURCE_TYPE_DEVICE);
2249     VERIFY_NON_NULL(TAG, deviceRsrc->types[0], ERROR);
2250     deviceRsrc->interfaceLen = 2;
2251     deviceRsrc->interfaces = (char**)OICCalloc(deviceRsrc->interfaceLen, sizeof(char*));
2252     VERIFY_NON_NULL(TAG, deviceRsrc->interfaces, ERROR);
2253     deviceRsrc->interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
2254     VERIFY_NON_NULL(TAG, deviceRsrc->interfaces[0], ERROR);
2255     deviceRsrc->interfaces[1] = OICStrdup(OC_RSRVD_INTERFACE_READ);
2256     VERIFY_NON_NULL(TAG, deviceRsrc->interfaces[1], ERROR);
2257
2258     // /oic/p
2259     platformRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
2260     VERIFY_NON_NULL(TAG, platformRsrc, ERROR);
2261     LL_APPEND(ace->resources, platformRsrc);
2262     platformRsrc->href = OICStrdup(OC_RSRVD_PLATFORM_URI);
2263     VERIFY_NON_NULL(TAG, (platformRsrc->href), ERROR);
2264     platformRsrc->typeLen = 1;
2265     platformRsrc->types = (char**)OICCalloc(1, sizeof(char*));
2266     VERIFY_NON_NULL(TAG, platformRsrc->types, ERROR);
2267     platformRsrc->types[0] = OICStrdup(OC_RSRVD_RESOURCE_TYPE_PLATFORM);
2268     VERIFY_NON_NULL(TAG, platformRsrc->types[0], ERROR);
2269     platformRsrc->interfaceLen = 2;
2270     platformRsrc->interfaces = (char**)OICCalloc(platformRsrc->interfaceLen, sizeof(char*));
2271     VERIFY_NON_NULL(TAG, platformRsrc->interfaces, ERROR);
2272     platformRsrc->interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
2273     VERIFY_NON_NULL(TAG, platformRsrc->interfaces[0], ERROR);
2274     platformRsrc->interfaces[1] = OICStrdup(OC_RSRVD_INTERFACE_READ);
2275     VERIFY_NON_NULL(TAG, platformRsrc->interfaces[1], ERROR);
2276
2277     // /oic/sec/acl
2278     aclRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
2279     VERIFY_NON_NULL(TAG, aclRsrc, ERROR);
2280     LL_APPEND(ace->resources, aclRsrc);
2281     aclRsrc->href = OICStrdup(OIC_RSRC_ACL_URI);
2282     VERIFY_NON_NULL(TAG, (aclRsrc->href), ERROR);
2283     aclRsrc->typeLen = 1;
2284     aclRsrc->types = (char**)OICCalloc(1, sizeof(char*));
2285     VERIFY_NON_NULL(TAG, aclRsrc->types, ERROR);
2286     aclRsrc->types[0] = OICStrdup(OIC_RSRC_TYPE_SEC_ACL);
2287     VERIFY_NON_NULL(TAG, aclRsrc->types[0], ERROR);
2288     aclRsrc->interfaceLen = 1;
2289     aclRsrc->interfaces = (char**)OICCalloc(aclRsrc->interfaceLen, sizeof(char*));
2290     VERIFY_NON_NULL(TAG, aclRsrc->interfaces, ERROR);
2291     aclRsrc->interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
2292     VERIFY_NON_NULL(TAG, aclRsrc->interfaces[0], ERROR);
2293
2294     // /oic/sec/doxm
2295     doxmRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
2296     VERIFY_NON_NULL(TAG, doxmRsrc, ERROR);
2297     LL_APPEND(ace->resources, doxmRsrc);
2298     doxmRsrc->href = OICStrdup(OIC_RSRC_DOXM_URI);
2299     VERIFY_NON_NULL(TAG, (doxmRsrc->href), ERROR);
2300     doxmRsrc->typeLen = 1;
2301     doxmRsrc->types = (char**)OICCalloc(1, sizeof(char*));
2302     VERIFY_NON_NULL(TAG, doxmRsrc->types, ERROR);
2303     doxmRsrc->types[0] = OICStrdup(OIC_RSRC_TYPE_SEC_DOXM);
2304     VERIFY_NON_NULL(TAG, doxmRsrc->types[0], ERROR);
2305     doxmRsrc->interfaceLen = 1;
2306     doxmRsrc->interfaces = (char**)OICCalloc(doxmRsrc->interfaceLen, sizeof(char*));
2307     VERIFY_NON_NULL(TAG, doxmRsrc->interfaces, ERROR);
2308     doxmRsrc->interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
2309     VERIFY_NON_NULL(TAG, doxmRsrc->interfaces[0], ERROR);
2310
2311     // /oic/sec/pstat
2312     pstatRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
2313     VERIFY_NON_NULL(TAG, pstatRsrc, ERROR);
2314     LL_APPEND(ace->resources, pstatRsrc);
2315     pstatRsrc->href = OICStrdup(OIC_RSRC_PSTAT_URI);
2316     VERIFY_NON_NULL(TAG, (pstatRsrc->href), ERROR);
2317     pstatRsrc->typeLen = 1;
2318     pstatRsrc->types = (char**)OICCalloc(1, sizeof(char*));
2319     VERIFY_NON_NULL(TAG, pstatRsrc->types, ERROR);
2320     pstatRsrc->types[0] = OICStrdup(OIC_RSRC_TYPE_SEC_PSTAT);
2321     VERIFY_NON_NULL(TAG, pstatRsrc->types[0], ERROR);
2322     pstatRsrc->interfaceLen = 1;
2323     pstatRsrc->interfaces = (char**)OICCalloc(pstatRsrc->interfaceLen, sizeof(char*));
2324     VERIFY_NON_NULL(TAG, pstatRsrc->interfaces, ERROR);
2325     pstatRsrc->interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
2326     VERIFY_NON_NULL(TAG, pstatRsrc->interfaces[0], ERROR);
2327
2328     ace->permission = PERMISSION_READ;
2329     ace->validities = NULL;
2330
2331     // Device ID is the owner of this default ACL
2332     if (GetDoxmResourceData() != NULL)
2333     {
2334         ret = GetDoxmDeviceID(&ownerId);
2335         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, FATAL);
2336     }
2337     else
2338     {
2339         OCRandomUuidResult rdm = OCGenerateUuid(ownerId.id);
2340         VERIFY_SUCCESS(TAG, RAND_UUID_OK == rdm, FATAL);
2341     }
2342
2343     memcpy(&acl->rownerID, &ownerId, sizeof(OicUuid_t));
2344
2345     *defaultAcl = acl;
2346     ret = OC_STACK_OK;
2347
2348 exit:
2349
2350     if (ret != OC_STACK_OK)
2351     {
2352         DeleteACLList(acl);
2353         acl = NULL;
2354     }
2355
2356     return ret;
2357 }
2358
2359 OCStackResult InitACLResource()
2360 {
2361     OCStackResult ret = OC_STACK_ERROR;
2362
2363     uint8_t *data = NULL;
2364     size_t size = 0;
2365     ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_ACL_NAME, &data, &size);
2366     // If database read failed
2367     if (OC_STACK_OK != ret)
2368     {
2369         OIC_LOG(DEBUG, TAG, "ReadSVDataFromPS failed");
2370     }
2371     if (data)
2372     {
2373         // Read ACL resource from PS
2374         gAcl = CBORPayloadToAcl(data, size);
2375         OICFree(data);
2376     }
2377     /*
2378      * If SVR database in persistent storage got corrupted or
2379      * is not available for some reason, a default ACL is created
2380      * which allows user to initiate ACL provisioning again.
2381      */
2382     if (!gAcl)
2383     {
2384         ret = GetDefaultACL(&gAcl);
2385         if (OC_STACK_OK != ret)
2386         {
2387             OIC_LOG(ERROR, TAG, "Failed to create default ACL");
2388         }
2389         // TODO Needs to update persistent storage
2390     }
2391     VERIFY_NON_NULL(TAG, gAcl, FATAL);
2392
2393     // Instantiate 'oic.sec.acl'
2394     ret = CreateACLResource();
2395
2396 exit:
2397     if (OC_STACK_OK != ret)
2398     {
2399         DeInitACLResource();
2400     }
2401     return ret;
2402 }
2403
2404 OCStackResult DeInitACLResource()
2405 {
2406     OCStackResult ret =  OCDeleteResource(gAclHandle);
2407     gAclHandle = NULL;
2408
2409     if (gAcl)
2410     {
2411         DeleteACLList(gAcl);
2412         gAcl = NULL;
2413     }
2414     return ret;
2415 }
2416
2417 const OicSecAce_t* GetACLResourceData(const OicUuid_t* subjectId, OicSecAce_t **savePtr)
2418 {
2419     OicSecAce_t *ace = NULL;
2420     OicSecAce_t *begin = NULL;
2421
2422     if (NULL == subjectId || NULL == savePtr || NULL == gAcl)
2423     {
2424         return NULL;
2425     }
2426
2427     /*
2428      * savePtr MUST point to NULL if this is the 'first' call to retrieve ACL for
2429      * subjectID.
2430      */
2431     if (NULL == *savePtr)
2432     {
2433         begin = gAcl->aces;
2434     }
2435     else
2436     {
2437         /*
2438          * If this is a 'successive' call, search for location pointed by
2439          * savePtr and assign 'begin' to the next ACL after it in the linked
2440          * list and start searching from there.
2441          */
2442         LL_FOREACH(gAcl->aces, ace)
2443         {
2444             if (ace == *savePtr)
2445             {
2446                 begin = ace->next;
2447             }
2448         }
2449     }
2450
2451     // Find the next ACL corresponding to the 'subjectID' and return it.
2452     LL_FOREACH(begin, ace)
2453     {
2454         if (memcmp(&(ace->subjectuuid), subjectId, sizeof(OicUuid_t)) == 0)
2455         {
2456             *savePtr = ace;
2457             return ace;
2458         }
2459     }
2460
2461     // Cleanup in case no ACL is found
2462     *savePtr = NULL;
2463     return NULL;
2464 }
2465
2466 void printACL(const OicSecAcl_t* acl)
2467 {
2468     OIC_LOG(INFO, TAG, "Print ACL:");
2469
2470     if (NULL == acl)
2471     {
2472         OIC_LOG(INFO, TAG, "Received NULL acl");
2473         return;
2474     }
2475
2476     char *rowner = NULL;
2477     if (OC_STACK_OK == ConvertUuidToStr(&acl->rownerID, &rowner))
2478     {
2479         OIC_LOG_V(INFO, TAG, "rowner id = %s", rowner);
2480     }
2481     else
2482     {
2483         OIC_LOG(ERROR, TAG, "Can't convert rowner uuid to string");
2484     }
2485     OICFree(rowner);
2486
2487     const OicSecAce_t *ace = acl->aces;
2488     int ace_count = 0;
2489     while (ace)
2490     {
2491         ace_count++;
2492         OIC_LOG_V(INFO, TAG, "Print ace[%d]:", ace_count);
2493
2494         OIC_LOG_V(INFO, TAG, "ace permission = %d", ace->permission);
2495
2496         char *subjectuuid = NULL;
2497         if (OC_STACK_OK == ConvertUuidToStr(&ace->subjectuuid, &subjectuuid))
2498         {
2499             OIC_LOG_V(INFO, TAG, "ace subject uuid = %s", subjectuuid);
2500         }
2501         else
2502         {
2503             OIC_LOG(ERROR, TAG, "Can't convert subjectuuid to string");
2504         }
2505         OICFree(subjectuuid);
2506
2507         OicSecRsrc_t *res = ace->resources;
2508         int res_count = 0;
2509         while (res)
2510         {
2511             res_count++;
2512             OIC_LOG_V(INFO, TAG, "Print resources[%d]:", res_count);
2513
2514             OIC_LOG_V(INFO, TAG, "href = %s", res->href);
2515
2516             for (size_t i = 0; i < res->typeLen; i++)
2517             {
2518                 OIC_LOG_V(INFO, TAG, "if[%zu] = %s", i, res->types[i]);
2519             }
2520             for (size_t i = 0; i < res->interfaceLen; i++)
2521             {
2522                 OIC_LOG_V(INFO, TAG, "if[%zu] = %s", i, res->interfaces[i]);
2523             }
2524
2525             res= res->next;
2526         }
2527
2528         OicSecValidity_t *vals = ace->validities;
2529         int vals_count = 0;
2530         while (vals)
2531         {
2532             vals_count++;
2533             OIC_LOG_V(INFO, TAG, "Print validities[%d]:", vals_count);
2534
2535             OIC_LOG_V(INFO, TAG, "period = %s", vals->period);
2536             for (size_t i = 0; i < vals->recurrenceLen; i++)
2537             {
2538                 OIC_LOG_V(INFO, TAG, "recurrences[%zu] = %s", i, vals->recurrences[i]);
2539             }
2540         }
2541
2542         ace = ace->next;
2543     }
2544 }
2545
2546 OCStackResult AppendACL2(const OicSecAcl_t* acl)
2547 {
2548     OCStackResult ret = OC_STACK_ERROR;
2549
2550     OIC_LOG_V(DEBUG, TAG, "IN: %s", __func__);
2551
2552     if (!acl)
2553     {
2554         OIC_LOG_V(ERROR, TAG, "%s: acl is NULL", __func__);
2555         return OC_STACK_INVALID_PARAM;
2556     }
2557
2558     if (!gAcl)
2559     {
2560         OIC_LOG_V(ERROR, TAG, "%s: gAcl is NULL", __func__);
2561         return OC_STACK_INVALID_PARAM;
2562     }
2563
2564     // Append the new ACE to existing ACE list
2565     // Can't use LL_APPEND because it sets ace->next to NULL
2566     OicSecAce_t* ace = gAcl->aces;
2567     if (ace)
2568     {
2569         while (ace->next)
2570         {
2571             ace = ace->next;
2572         }
2573         ace->next = acl->aces;
2574     }
2575     else
2576     {
2577         gAcl->aces = acl->aces;
2578     }
2579
2580     printACL(gAcl);
2581
2582     size_t size = 0;
2583     uint8_t *payload = NULL;
2584     ret = AclToCBORPayload(gAcl, &payload, &size);
2585     if (OC_STACK_OK == ret)
2586     {
2587         ret = UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, payload, size);
2588         OICFree(payload);
2589     }
2590
2591     OIC_LOG_V(DEBUG, TAG, "OUT: %s", __func__);
2592
2593     return ret;
2594 }
2595
2596 OCStackResult AppendACL(const uint8_t *cborPayload, const size_t size)
2597 {
2598     // Convert CBOR format to ACL data. This will also validate the ACL data received.
2599     OicSecAcl_t* newAcl = CBORPayloadToAcl(cborPayload, size);
2600
2601     return AppendACL2(newAcl);
2602 }
2603
2604 OCStackResult InstallACL(const OicSecAcl_t* acl)
2605 {
2606     OIC_LOG_V(DEBUG, TAG, "IN: %s", __func__);
2607
2608     OCStackResult ret = OC_STACK_ERROR;
2609
2610     if (!acl)
2611     {
2612         OIC_LOG_V(ERROR, TAG, "%s: acl is NULL", __func__);
2613         return OC_STACK_INVALID_PARAM;
2614     }
2615
2616     if (!gAcl)
2617     {
2618         OIC_LOG_V(ERROR, TAG, "%s: gAcl is NULL", __func__);
2619         return OC_STACK_INVALID_PARAM;
2620     }
2621
2622     bool isNewAce = true;
2623     OicSecAce_t* existAce = NULL;
2624     OicSecAce_t* newAce = NULL;
2625     OicSecAce_t* tempAce1 = NULL;
2626     OicSecAce_t* tempAce2 = NULL;
2627     OicSecAcl_t* newInstallAcl = NULL;
2628
2629     LL_FOREACH_SAFE(acl->aces, newAce, tempAce1)
2630     {
2631         isNewAce = true;
2632         LL_FOREACH_SAFE(gAcl->aces, existAce, tempAce2)
2633         {
2634             if(IsSameACE(newAce, existAce))
2635             {
2636                 OIC_LOG(DEBUG, TAG, "Duplicated ACE dectected.");
2637                 ret = OC_STACK_DUPLICATE_REQUEST;
2638                 isNewAce = false;
2639             }
2640         }
2641         if(isNewAce)
2642         {
2643             // Append new ACE to existing ACL
2644             OIC_LOG(DEBUG, TAG, "NEW ACE dectected.");
2645
2646             OicSecAce_t* insertAce = DuplicateACE(newAce);
2647             if(insertAce)
2648             {
2649                 OIC_LOG(DEBUG, TAG, "Appending new ACE..");
2650
2651                 if (!newInstallAcl)
2652                 {
2653                     newInstallAcl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
2654                     if (NULL == newInstallAcl)
2655                     {
2656                         OIC_LOG(ERROR, TAG, "Failed to acllocate ACL");
2657                         return OC_STACK_NO_MEMORY;
2658                     }
2659                 }
2660                 LL_PREPEND(newInstallAcl->aces, insertAce);
2661             }
2662             else
2663             {
2664                 OIC_LOG(ERROR, TAG, "Failed to duplicate ACE");
2665                 DeleteACLList(newInstallAcl);
2666                 return OC_STACK_ERROR;
2667             }
2668         }
2669     }
2670
2671     if (newInstallAcl)
2672     {
2673         ret = AppendACL2(newInstallAcl);
2674         if (OC_STACK_OK != ret)
2675         {
2676             OIC_LOG(ERROR, TAG, "Failed to append ACL");
2677         }
2678         OICFree(newInstallAcl);
2679     }
2680
2681     OIC_LOG_V(DEBUG, TAG, "OUT: %s", __func__);
2682     
2683     return ret;
2684 }
2685
2686 /**
2687  * This function generates default ACE for security resource in case of owned status.
2688  *
2689  * @return Default ACE for security resource.
2690  */
2691 static OicSecAce_t* GetSecDefaultACE()
2692 {
2693     const int NUM_OF_DOXM_RT = 1;
2694     const int NUM_OF_DOXM_IF  = 1;
2695     const int NUM_OF_PSTAT_RT = 1;
2696     const int NUM_OF_PSTAT_IF = 1;
2697     const char *doxmRt[] = { OIC_RSRC_TYPE_SEC_DOXM };
2698     const char *pstatRt[] = { OIC_RSRC_TYPE_SEC_PSTAT };
2699     const char *doxmIf[] = { OC_RSRVD_INTERFACE_DEFAULT };
2700     const char *pstatIf[] = { OC_RSRVD_INTERFACE_DEFAULT };
2701     OicSecRsrc_t* doxmRsrc = NULL;
2702     OicSecRsrc_t* pstatRsrc = NULL;
2703
2704     //Generate default ACE
2705     OicSecAce_t* newAce = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
2706     VERIFY_NON_NULL(TAG, newAce, ERROR);
2707
2708     // Subject -- Mandatory
2709     memcpy(newAce->subjectuuid.id, &WILDCARD_SUBJECT_ID, WILDCARD_SUBJECT_ID_LEN);
2710
2711     //Resources -- Mandatory
2712     //Add doxm
2713     doxmRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
2714     VERIFY_NON_NULL(TAG, doxmRsrc, ERROR);
2715     LL_APPEND(newAce->resources, doxmRsrc);
2716     // pstat-href
2717     doxmRsrc->href = OICStrdup(OIC_RSRC_DOXM_URI);
2718     VERIFY_NON_NULL(TAG, (doxmRsrc->href), ERROR);
2719     // pstat-rt
2720     doxmRsrc->typeLen = NUM_OF_DOXM_RT;
2721     doxmRsrc->types = (char**)OICCalloc(NUM_OF_DOXM_RT, sizeof(char*));
2722     VERIFY_NON_NULL(TAG, (doxmRsrc->types), ERROR);
2723     for(int i = 0; i < NUM_OF_DOXM_RT; i++)
2724     {
2725         doxmRsrc->types[i] = OICStrdup(doxmRt[i]);
2726         VERIFY_NON_NULL(TAG, (doxmRsrc->types[i]), ERROR);
2727     }
2728     // pstat-if
2729     doxmRsrc->interfaceLen = NUM_OF_DOXM_IF;
2730     doxmRsrc->interfaces = (char**)OICCalloc(NUM_OF_DOXM_IF, sizeof(char*));
2731     VERIFY_NON_NULL(TAG, (doxmRsrc->interfaces), ERROR);
2732     for(int i = 0; i < NUM_OF_DOXM_IF; i++)
2733     {
2734         doxmRsrc->interfaces[i] = OICStrdup(doxmIf[i]);
2735         VERIFY_NON_NULL(TAG, (doxmRsrc->interfaces[i]), ERROR);
2736     }
2737
2738     //Add pstat
2739     pstatRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
2740     VERIFY_NON_NULL(TAG, pstatRsrc, ERROR);
2741     LL_APPEND(newAce->resources, pstatRsrc);
2742     //pstat-href
2743     pstatRsrc->href = OICStrdup(OIC_RSRC_PSTAT_URI);
2744     VERIFY_NON_NULL(TAG, (pstatRsrc->href), ERROR);
2745     //pstat-rt
2746     pstatRsrc->typeLen = NUM_OF_PSTAT_RT;
2747     pstatRsrc->types = (char**)OICCalloc(NUM_OF_PSTAT_RT, sizeof(char*));
2748     VERIFY_NON_NULL(TAG, (pstatRsrc->types), ERROR);
2749     for(int i = 0; i < NUM_OF_PSTAT_RT; i++)
2750     {
2751         pstatRsrc->types[i] = OICStrdup(pstatRt[i]);
2752         VERIFY_NON_NULL(TAG, (pstatRsrc->types[i]), ERROR);
2753     }
2754     // pstat-if
2755     pstatRsrc->interfaceLen = NUM_OF_PSTAT_IF;
2756     pstatRsrc->interfaces = (char**)OICCalloc(NUM_OF_PSTAT_IF, sizeof(char*));
2757     VERIFY_NON_NULL(TAG, (pstatRsrc->interfaces), ERROR);
2758     for(int i = 0; i < NUM_OF_PSTAT_IF; i++)
2759     {
2760         pstatRsrc->interfaces[i] = OICStrdup(pstatIf[i]);
2761         VERIFY_NON_NULL(TAG, (pstatRsrc->interfaces[i]), ERROR);
2762     }
2763
2764     // Permissions -- Mandatory
2765     newAce->permission = PERMISSION_READ;
2766
2767     //Period -- Not Mandatory
2768     newAce->validities = NULL;
2769
2770     return newAce;
2771 exit:
2772     FreeACE(newAce);
2773     return NULL;
2774
2775 }
2776
2777 OCStackResult UpdateDefaultSecProvACE()
2778 {
2779     OCStackResult ret = OC_STACK_OK;
2780     OicSecAce_t *ace = NULL;
2781     OicSecAce_t *tempAce = NULL;
2782
2783     if(gAcl)
2784     {
2785         int matchedRsrc = 0;
2786         bool isRemoved = false;
2787
2788         LL_FOREACH_SAFE(gAcl->aces, ace, tempAce)
2789         {
2790             //Find default security resource ACL
2791             if(memcmp(&ace->subjectuuid, &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t)) == 0 &&
2792                 ((PERMISSION_READ | PERMISSION_WRITE) == ace->permission))
2793             {
2794                 matchedRsrc = 0;
2795
2796                 OicSecRsrc_t* rsrc = NULL;
2797                 LL_FOREACH(ace->resources, rsrc)
2798                 {
2799                     if(strncmp(rsrc->href, OIC_RSRC_DOXM_URI,
2800                                strlen(OIC_RSRC_DOXM_URI) + 1) == 0 ||
2801                        strncmp(rsrc->href, OIC_RSRC_CRED_URI,
2802                                strlen(OIC_RSRC_CRED_URI) + 1) == 0 ||
2803                        strncmp(rsrc->href, OIC_RSRC_PSTAT_URI,
2804                                strlen(OIC_RSRC_PSTAT_URI) + 1) == 0)
2805                     {
2806                         matchedRsrc++;
2807                     }
2808                 }
2809
2810                 //If default security resource ACL is detected, delete it.
2811                 if(NUMBER_OF_SEC_PROV_RSCS == matchedRsrc)
2812                 {
2813                     LL_DELETE(gAcl->aces, ace);
2814                     FreeACE(ace);
2815                     isRemoved = true;
2816                 }
2817             }
2818         }
2819
2820         if(isRemoved)
2821         {
2822             /*
2823              * Generate new security resource ACE as follows :
2824              *      subject : "*"
2825              *      resources :  '/oic/sec/doxm', '/oic/sec/pstat'
2826              *      permission : READ
2827              */
2828             OicSecAce_t *secDefaultAce = GetSecDefaultACE();
2829             if (secDefaultAce)
2830             {
2831                 LL_APPEND(gAcl->aces, secDefaultAce);
2832
2833                 size_t size = 0;
2834                 uint8_t *payload = NULL;
2835                 if (OC_STACK_OK == AclToCBORPayload(gAcl, &payload, &size))
2836                 {
2837                     if (UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, payload, size) == OC_STACK_OK)
2838                     {
2839                         ret = OC_STACK_OK;
2840                     }
2841                     OICFree(payload);
2842                 }
2843             }
2844         }
2845     }
2846
2847     return ret;
2848 }
2849
2850 OCStackResult SetAclRownerId(const OicUuid_t* newROwner)
2851 {
2852     OCStackResult ret = OC_STACK_ERROR;
2853     uint8_t *cborPayload = NULL;
2854     size_t size = 0;
2855     OicUuid_t prevId = {.id={0}};
2856
2857     if(NULL == newROwner)
2858     {
2859         ret = OC_STACK_INVALID_PARAM;
2860     }
2861     if(NULL == gAcl)
2862     {
2863         ret = OC_STACK_NO_RESOURCE;
2864     }
2865
2866     if(newROwner && gAcl)
2867     {
2868         memcpy(prevId.id, gAcl->rownerID.id, sizeof(prevId.id));
2869         memcpy(gAcl->rownerID.id, newROwner->id, sizeof(newROwner->id));
2870
2871         ret = AclToCBORPayload(gAcl, &cborPayload, &size);
2872         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2873
2874         ret = UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, cborPayload, size);
2875         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2876
2877         OICFree(cborPayload);
2878     }
2879
2880     return ret;
2881
2882 exit:
2883     OICFree(cborPayload);
2884     memcpy(gAcl->rownerID.id, prevId.id, sizeof(prevId.id));
2885     return ret;
2886 }
2887
2888 OCStackResult GetAclRownerId(OicUuid_t *rowneruuid)
2889 {
2890     OCStackResult retVal = OC_STACK_ERROR;
2891     if (gAcl)
2892     {
2893         *rowneruuid = gAcl->rownerID;
2894         retVal = OC_STACK_OK;
2895     }
2896     return retVal;
2897 }