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