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