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