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