Merge remote-tracking branch 'origin/notification-service'
[platform/upstream/iotivity.git] / resource / csdk / security / src / aclresource.c
1 //******************************************************************
2 //
3 // Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #include "iotivity_config.h"
22 #ifdef HAVE_STRING_H
23 #include <string.h>
24 #elif defined(HAVE_STRINGS_H)
25 #include <strings.h>
26 #endif
27 #include <stdlib.h>
28
29 #include "utlist.h"
30 #include "ocstack.h"
31 #include "octypes.h"
32 #include "ocserverrequest.h"
33 #include "oic_malloc.h"
34 #include "oic_string.h"
35 #include "ocrandom.h"
36 #include "ocpayload.h"
37 #include "utlist.h"
38 #include "payload_logging.h"
39 #include "srmresourcestrings.h"
40 #include "aclresource.h"
41 #include "doxmresource.h"
42 #include "resourcemanager.h"
43 #include "srmutility.h"
44 #include "psinterface.h"
45
46 #include "security_internals.h"
47
48 #define TAG  "SRM-ACL"
49 #define NUMBER_OF_SEC_PROV_RSCS 4
50 #define NUMBER_OF_DEFAULT_SEC_RSCS 2
51 #define STRING_UUID_SIZE (UUID_LENGTH * 2 + 5)
52
53 static const uint8_t ACL_MAP_SIZE = 4;
54 static const uint8_t ACL_ACLIST_MAP_SIZE = 1;
55 static const uint8_t ACL_ACES_MAP_SIZE = 3;
56 static const uint8_t ACL_RESOURCE_MAP_SIZE = 3;
57
58
59 // CborSize is the default cbor payload size being used.
60 static const uint16_t CBOR_SIZE = 2048;
61
62 static OicSecAcl_t *gAcl = NULL;
63 static OCResourceHandle gAclHandle = NULL;
64
65 /**
66  * This function frees OicSecRsrc_t object's fields and object itself.
67  */
68 static void FreeRsrc(OicSecRsrc_t *rsrc)
69 {
70     //Clean each member of resource
71     OICFree(rsrc->href);
72     OICFree(rsrc->rel);
73     //Clean "rt"
74     if(0 < rsrc->typeLen && rsrc->types)
75     {
76         for(size_t i = 0; i < rsrc->typeLen; i++)
77         {
78             OICFree(rsrc->types[i]);
79         }
80         OICFree(rsrc->types);
81         rsrc->types = NULL;
82     }
83     //Clean "if"
84     if(0 < rsrc->interfaceLen && rsrc->interfaces)
85     {
86         for(size_t i = 0; i < rsrc->interfaceLen; i++)
87         {
88             OICFree(rsrc->interfaces[i]);
89         }
90         OICFree(rsrc->interfaces);
91         rsrc->interfaces = NULL;
92     }
93     OICFree(rsrc);
94     rsrc = NULL;
95 }
96
97 /**
98  * This function frees OicSecAcl_t object's fields and object itself.
99  */
100 static void FreeACE(OicSecAce_t *ace)
101 {
102     if (NULL == ace)
103     {
104         OIC_LOG(ERROR, TAG, "Invalid Parameter");
105         return;
106     }
107
108     //Clean Resources
109     OicSecRsrc_t* rsrc = NULL;
110     OicSecRsrc_t* tmpRsrc = NULL;
111     LL_FOREACH_SAFE(ace->resources, rsrc, tmpRsrc)
112     {
113         LL_DELETE(ace->resources, rsrc);
114         FreeRsrc(rsrc);
115     }
116
117     //Clean Validities
118     OicSecValidity_t *validity = NULL;
119     OicSecValidity_t *tmpValidity = NULL;
120     LL_FOREACH_SAFE(ace->validities, validity, tmpValidity)
121     {
122         LL_DELETE(ace->validities, validity);
123
124         //Clean period
125         OICFree(validity->period);
126
127         //Clean recurrence
128         for(size_t i = 0; i < validity->recurrenceLen; i++)
129         {
130             OICFree(validity->recurrences[i]);
131         }
132         OICFree(validity->recurrences);
133         OICFree(validity);
134         validity = NULL;
135     }
136
137     //Clean ACE
138     OICFree(ace);
139     ace = NULL;
140 }
141
142 void DeleteACLList(OicSecAcl_t* acl)
143 {
144     if (acl)
145     {
146         OicSecAce_t *ace = NULL;
147         OicSecAce_t *tmpAce = NULL;
148         LL_FOREACH_SAFE(acl->aces, ace, tmpAce)
149         {
150             LL_DELETE(acl->aces, ace);
151             FreeACE(ace);
152         }
153         acl->aces = NULL;
154         OICFree(acl);
155     }
156 }
157
158 OicSecAce_t* DuplicateACE(const OicSecAce_t* ace)
159 {
160     OicSecAce_t* newAce = NULL;
161     size_t allocateSize = 0;
162
163     if(ace)
164     {
165         newAce = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
166         VERIFY_NON_NULL(TAG, newAce, ERROR);
167
168         //Subject uuid
169         memcpy(&newAce->subjectuuid, &ace->subjectuuid, sizeof(OicUuid_t));
170
171         OicSecRsrc_t* rsrc = NULL;
172         LL_FOREACH(ace->resources, rsrc)
173         {
174             OicSecRsrc_t* newRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
175             VERIFY_NON_NULL(TAG, newRsrc, ERROR);
176             LL_APPEND(newAce->resources, newRsrc);
177
178             //href is mandatory
179             VERIFY_NON_NULL(TAG, rsrc->href, ERROR);
180             allocateSize = strlen(rsrc->href) + 1;
181             newRsrc->href = (char*)OICMalloc(sizeof(char) * allocateSize);
182             VERIFY_NON_NULL(TAG, newRsrc->href, ERROR);
183             OICStrcpy(newRsrc->href, allocateSize, rsrc->href);
184
185             if(rsrc->rel)
186             {
187                 allocateSize = strlen(rsrc->rel) + 1;
188                 newRsrc->rel = (char*)OICMalloc(sizeof(char) * allocateSize);
189                 VERIFY_NON_NULL(TAG, newRsrc->rel, ERROR);
190                 OICStrcpy(newRsrc->rel, allocateSize, rsrc->rel);
191             }
192
193             if(rsrc->types && 0 < rsrc->typeLen)
194             {
195                 newRsrc->typeLen = rsrc->typeLen;
196                 newRsrc->types = (char**)OICCalloc(rsrc->typeLen, sizeof(char*));
197                 VERIFY_NON_NULL(TAG, (newRsrc->types), ERROR);
198                 for(size_t i = 0; i < rsrc->typeLen; i++)
199                 {
200                     newRsrc->types[i] = OICStrdup(rsrc->types[i]);
201                     VERIFY_NON_NULL(TAG, (newRsrc->types[i]), ERROR);
202                 }
203             }
204
205             if(rsrc->interfaces && 0 < rsrc->interfaceLen)
206             {
207                 newRsrc->interfaceLen = rsrc->interfaceLen;
208                 newRsrc->interfaces = (char**)OICCalloc(rsrc->interfaceLen, sizeof(char*));
209                 VERIFY_NON_NULL(TAG, (newRsrc->interfaces), ERROR);
210                 for(size_t i = 0; i < rsrc->interfaceLen; i++)
211                 {
212                     newRsrc->interfaces[i] = OICStrdup(rsrc->interfaces[i]);
213                     VERIFY_NON_NULL(TAG, (newRsrc->interfaces[i]), ERROR);
214                 }
215             }
216         }
217
218         //Permission
219         newAce->permission = ace->permission;
220
221         //Validity
222         if(ace->validities)
223         {
224             OicSecValidity_t* validity = NULL;
225             LL_FOREACH(ace->validities, validity)
226             {
227                 OicSecValidity_t* newValidity = (OicSecValidity_t*)OICCalloc(1, sizeof(OicSecValidity_t));
228                 VERIFY_NON_NULL(TAG, newValidity, ERROR);
229                 LL_APPEND(newAce->validities, newValidity);
230
231                 if(validity->period)
232                 {
233                     allocateSize = strlen(validity->period) + 1;
234                     newValidity->period = (char*)OICMalloc(sizeof(char) * allocateSize);
235                     VERIFY_NON_NULL(TAG, newValidity->period, ERROR);
236                     OICStrcpy(newValidity->period, allocateSize, validity->period);
237                 }
238
239                 if(validity->recurrences && 0 < validity->recurrenceLen)
240                 {
241                     newValidity->recurrenceLen = validity->recurrenceLen;
242
243                     newValidity->recurrences = (char**)OICMalloc(sizeof(char*) * validity->recurrenceLen);
244                     VERIFY_NON_NULL(TAG, newValidity->recurrences, ERROR);
245
246                     for(size_t i = 0; i < validity->recurrenceLen; i++)
247                     {
248                         allocateSize = strlen(validity->recurrences[i]) + 1;
249                         newValidity->recurrences[i] = (char*)OICMalloc(sizeof(char) * allocateSize);
250                         VERIFY_NON_NULL(TAG, (newValidity->recurrences[i]), ERROR);
251                         OICStrcpy(newValidity->recurrences[i], allocateSize, validity->recurrences[i]);
252                     }
253                 }
254             }
255         }
256
257         newAce->next = NULL;
258     }
259
260     return newAce;
261
262 exit:
263     FreeACE(newAce);
264     return NULL;
265 }
266
267 static size_t OicSecAclSize(const OicSecAcl_t *secAcl)
268 {
269     if (!secAcl)
270     {
271         return 0;
272     }
273     OicSecAce_t *ace= (OicSecAce_t *)secAcl->aces;
274     size_t size = 0;
275     while (ace)
276     {
277        size++;
278        ace = ace->next;
279     }
280     return size;
281 }
282
283 OCStackResult AclToCBORPayload(const OicSecAcl_t *secAcl, uint8_t **payload, size_t *size)
284 {
285      if (NULL == secAcl || NULL == payload || NULL != *payload || NULL == size)
286     {
287         return OC_STACK_INVALID_PARAM;
288     }
289
290     OCStackResult ret = OC_STACK_ERROR;
291     CborError cborEncoderResult = CborNoError;
292     OicSecAcl_t *acl = (OicSecAcl_t *)secAcl;
293     OicSecAce_t* ace = NULL;
294     CborEncoder encoder;
295     CborEncoder aclMap;
296     CborEncoder aclListMap;
297     CborEncoder acesArray;
298     uint8_t *outPayload = NULL;
299     size_t cborLen = *size;
300     *size = 0;
301     *payload = NULL;
302
303     if (cborLen == 0)
304     {
305         cborLen = CBOR_SIZE;
306     }
307
308     outPayload = (uint8_t *)OICCalloc(1, cborLen);
309     VERIFY_NON_NULL(TAG, outPayload, ERROR);
310     cbor_encoder_init(&encoder, outPayload, cborLen, 0);
311
312     // Create ACL Map (aclist, rownerid)
313     cborEncoderResult = cbor_encoder_create_map(&encoder, &aclMap, ACL_MAP_SIZE);
314     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating ACL Map.");
315
316     cborEncoderResult = cbor_encode_text_string(&aclMap, OIC_JSON_ACLIST_NAME,
317         strlen(OIC_JSON_ACLIST_NAME));
318     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding aclist Name Tag.");
319
320     // Create ACLIST Map (aces)
321     cborEncoderResult = cbor_encoder_create_map(&aclMap, &aclListMap, ACL_ACLIST_MAP_SIZE);
322     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating ACLIST Map.");
323
324     cborEncoderResult = cbor_encode_text_string(&aclListMap, OIC_JSON_ACES_NAME,
325         strlen(OIC_JSON_ACES_NAME));
326     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACES Name Tag.");
327
328     // Create ACES Array
329     cborEncoderResult = cbor_encoder_create_array(&aclListMap, &acesArray, OicSecAclSize(secAcl));
330     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating ACES Array.");
331
332     ace = NULL;
333     LL_FOREACH (acl->aces, ace)
334     {
335         CborEncoder oicSecAclMap;
336         // ACL Map size - Number of mandatory items
337         uint8_t aclMapSize = ACL_ACES_MAP_SIZE;
338         size_t inLen = 0;
339
340         OicSecValidity_t* validityElts = ace->validities;
341         while(validityElts)
342         {
343             if(validityElts->period)
344             {
345                 aclMapSize++;
346             }
347             if(validityElts->recurrences)
348             {
349                 aclMapSize++;
350             }
351         }
352
353         cborEncoderResult = cbor_encoder_create_map(&acesArray, &oicSecAclMap, aclMapSize);
354         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating ACES Map");
355
356         // Subject -- Mandatory
357         cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, OIC_JSON_SUBJECTID_NAME,
358             strlen(OIC_JSON_SUBJECTID_NAME));
359         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Subject Name Tag.");
360         inLen = (memcmp(&(ace->subjectuuid), &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t)) == 0) ?
361             WILDCARD_SUBJECT_ID_LEN : sizeof(OicUuid_t);
362         if(inLen == WILDCARD_SUBJECT_ID_LEN)
363         {
364             cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, WILDCARD_RESOURCE_URI,
365                 strlen(WILDCARD_RESOURCE_URI));
366             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id wildcard Value.");
367         }
368         else
369         {
370             char *subject = NULL;
371             ret = ConvertUuidToStr(&ace->subjectuuid, &subject);
372             VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
373             cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, subject, strlen(subject));
374             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject UUID Value.");
375             OICFree(subject);
376         }
377
378         // Resources
379         {
380             CborEncoder resources;
381             cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, OIC_JSON_RESOURCES_NAME,
382                 strlen(OIC_JSON_RESOURCES_NAME));
383             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Resource Name Tag.");
384
385             size_t rsrcLen = 0;
386             OicSecRsrc_t* rsrcElts = NULL;
387             LL_FOREACH(ace->resources, rsrcElts)
388             {
389                 rsrcLen++;
390             }
391
392             cborEncoderResult = cbor_encoder_create_array(&oicSecAclMap, &resources, rsrcLen);
393             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Resource Name Array.");
394
395             OicSecRsrc_t* rsrc = NULL;
396             LL_FOREACH(ace->resources, rsrc)
397             {
398
399                 CborEncoder rMap;
400                 size_t rsrcMapSize = ACL_RESOURCE_MAP_SIZE;
401                 if(rsrc->rel)
402                 {
403                     rsrcMapSize++;
404                 }
405
406                 cborEncoderResult = cbor_encoder_create_map(&resources, &rMap, rsrcMapSize);
407                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Resource Map.");
408
409                 //href -- Mandatory
410                 VERIFY_NON_NULL(TAG, rsrc->href, ERROR);
411                 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_HREF_NAME,
412                         strlen(OIC_JSON_HREF_NAME));
413                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding HREF Name Tag.");
414                 cborEncoderResult = cbor_encode_text_string(&rMap, rsrc->href, strlen(rsrc->href));
415                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding HREF Value in Map.");
416
417                 //resource type -- Mandatory
418                 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_RT_NAME,
419                         strlen(OIC_JSON_RT_NAME));
420                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
421
422                 CborEncoder resourceTypes;
423                 cborEncoderResult = cbor_encoder_create_array(&rMap, &resourceTypes, rsrc->typeLen);
424                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding RT Array.");
425                 for(size_t i = 0; i < rsrc->typeLen; i++)
426                 {
427                     cborEncoderResult = cbor_encode_text_string(&resourceTypes, rsrc->types[i], strlen(rsrc->types[i]));
428                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Value.");
429                 }
430                 cborEncoderResult = cbor_encoder_close_container(&rMap, &resourceTypes);
431                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing resourceTypes.");
432
433                 //interface -- Mandatory
434                 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_IF_NAME,
435                         strlen(OIC_JSON_IF_NAME));
436                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
437
438                 CborEncoder interfaces;
439                 cborEncoderResult = cbor_encoder_create_array(&rMap, &interfaces, rsrc->interfaceLen);
440                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding IF Array.");
441                 for(size_t i = 0; i < rsrc->interfaceLen; i++)
442                 {
443                     cborEncoderResult = cbor_encode_text_string(&interfaces, rsrc->interfaces[i], strlen(rsrc->interfaces[i]));
444                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
445                 }
446                 cborEncoderResult = cbor_encoder_close_container(&rMap, &interfaces);
447                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing interfaces.");
448
449                 //rel
450                 if(rsrc->rel)
451                 {
452                     cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_REL_NAME,
453                             strlen(OIC_JSON_REL_NAME));
454                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding REL Name Tag.");
455                     cborEncoderResult = cbor_encode_text_string(&rMap, rsrc->rel, strlen(rsrc->rel));
456                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding REL Value.");
457                 }
458
459                 cborEncoderResult = cbor_encoder_close_container(&resources, &rMap);
460                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Resource Map.");
461             }
462             cborEncoderResult = cbor_encoder_close_container(&oicSecAclMap, &resources);
463             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Resource Name Array.");
464         }
465
466         // Permissions -- Mandatory
467         cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, OIC_JSON_PERMISSION_NAME,
468             strlen(OIC_JSON_PERMISSION_NAME));
469         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Permission Name Tag.");
470         cborEncoderResult = cbor_encode_int(&oicSecAclMap, ace->permission);
471         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Permission Name Value.");
472
473         // TODO: Need to verfication for validity
474         // Validity(Time-interval) -- Not Mandatory
475         if(ace->validities)
476         {
477             size_t validityLen = 0;
478             validityElts = NULL;
479             LL_FOREACH(ace->validities, validityElts)
480             {
481                 validityLen++;
482             }
483
484             CborEncoder validities;
485             cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, OIC_JSON_VALIDITY_NAME,
486                 strlen(OIC_JSON_VALIDITY_NAME));
487             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Validity Tag.");
488             cborEncoderResult = cbor_encoder_create_array(&oicSecAclMap, &validities, validityLen);
489             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Validities Array.");
490
491             //How to add the value w/o "title" using tinycobr...? :(
492
493             validityElts = NULL;
494             LL_FOREACH(ace->validities, validityElts)
495             {
496                  CborEncoder validity;
497                  size_t validitySize = 0;
498                  if(validityElts->period)
499                 {
500                     validitySize++;
501                 }
502                 if(validityElts->recurrences)
503                 {
504                     validitySize++;
505                 }
506
507                 cborEncoderResult = cbor_encoder_create_array(&validities, &validity, validitySize);
508                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Validity Array.");
509
510                 // Period
511                 if (validityElts->period)
512                 {
513                     cborEncoderResult = cbor_encode_text_string(&validity, validityElts->period,
514                         strlen(validityElts->period));
515                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Value.");
516                 }
517
518                 // Recurrence
519                 if (validityElts->recurrences)
520                 {
521                     CborEncoder recurrences;
522                     cborEncoderResult = cbor_encoder_create_array(&validity, &recurrences, validityElts->recurrenceLen);
523                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Recurrence Array.");
524
525                     for (size_t i = 0; i < validityElts->recurrenceLen; i++)
526                     {
527                         cborEncoderResult = cbor_encode_text_string(&recurrences, validityElts->recurrences[i],
528                             strlen(validityElts->recurrences[i]));
529                         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Recurrence Array Value.");
530                     }
531                     cborEncoderResult = cbor_encoder_close_container(&validity, &recurrences);
532                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Recurrence Array");
533                 }
534
535                 cborEncoderResult = cbor_encoder_close_container(&validities, &validity);
536                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Validity Array.");
537             }
538
539             cborEncoderResult = cbor_encoder_close_container(&oicSecAclMap, &validities);
540             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Validities Array.");
541         }
542
543         cborEncoderResult = cbor_encoder_close_container(&acesArray, &oicSecAclMap);
544         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing ACES Map.");
545     }
546
547     // Close ACES Array
548     cborEncoderResult = cbor_encoder_close_container(&aclListMap, &acesArray);
549     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing ACES Array.");
550
551     // Close ACLIST Map
552     cborEncoderResult = cbor_encoder_close_container(&aclMap, &aclListMap);
553     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing ACLIST Map.");
554
555     // Rownerid
556     {
557         char *rowner = NULL;
558         cborEncoderResult = cbor_encode_text_string(&aclMap, OIC_JSON_ROWNERID_NAME,
559             strlen(OIC_JSON_ROWNERID_NAME));
560         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding rownerid Name.");
561         ret = ConvertUuidToStr(&secAcl->rownerID, &rowner);
562         VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
563         cborEncoderResult = cbor_encode_text_string(&aclMap, rowner, strlen(rowner));
564         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding rownerid Value.");
565         OICFree(rowner);
566     }
567
568     //RT -- Mandatory
569     CborEncoder rtArray;
570     cborEncoderResult = cbor_encode_text_string(&aclMap, OIC_JSON_RT_NAME,
571             strlen(OIC_JSON_RT_NAME));
572     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
573     cborEncoderResult = cbor_encoder_create_array(&aclMap, &rtArray, 1);
574     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Value.");
575     for (size_t i = 0; i < 1; i++)
576     {
577         cborEncoderResult = cbor_encode_text_string(&rtArray, OIC_RSRC_TYPE_SEC_ACL,
578                 strlen(OIC_RSRC_TYPE_SEC_ACL));
579         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding RT Value.");
580     }
581     cborEncoderResult = cbor_encoder_close_container(&aclMap, &rtArray);
582     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing RT.");
583
584     //IF-- Mandatory
585     CborEncoder ifArray;
586     cborEncoderResult = cbor_encode_text_string(&aclMap, OIC_JSON_IF_NAME,
587              strlen(OIC_JSON_IF_NAME));
588     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
589     cborEncoderResult = cbor_encoder_create_array(&aclMap, &ifArray, 1);
590     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
591     for (size_t i = 0; i < 1; i++)
592     {
593         cborEncoderResult = cbor_encode_text_string(&ifArray, OC_RSRVD_INTERFACE_DEFAULT,
594                 strlen(OC_RSRVD_INTERFACE_DEFAULT));
595         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding IF Value.");
596     }
597     cborEncoderResult = cbor_encoder_close_container(&aclMap, &ifArray);
598     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing IF.");
599
600     // Close ACL Map
601     cborEncoderResult = cbor_encoder_close_container(&encoder, &aclMap);
602     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing ACL Map.");
603
604     if (CborNoError == cborEncoderResult)
605     {
606         OIC_LOG(DEBUG, TAG, "AclToCBORPayload Successed");
607         *size = encoder.ptr - outPayload;
608         *payload = outPayload;
609         ret = OC_STACK_OK;
610     }
611 exit:
612     if (CborErrorOutOfMemory == cborEncoderResult)
613     {
614         OIC_LOG(DEBUG, TAG, "AclToCBORPayload:CborErrorOutOfMemory : retry with more memory");
615
616         // reallocate and try again!
617         OICFree(outPayload);
618         // Since the allocated initial memory failed, double the memory.
619         cborLen += encoder.ptr - encoder.end;
620         cborEncoderResult = CborNoError;
621         ret = AclToCBORPayload(secAcl, payload, &cborLen);
622         *size = cborLen;
623     }
624     else if (cborEncoderResult != CborNoError)
625     {
626         OIC_LOG(ERROR, TAG, "Failed to AclToCBORPayload");
627         OICFree(outPayload);
628         outPayload = NULL;
629         *size = 0;
630         *payload = NULL;
631         ret = OC_STACK_ERROR;
632     }
633
634     return ret;
635 }
636
637 // This function converts CBOR format to ACL data.
638 // Caller needs to invoke 'free' when done using
639 // note: This function is used in unit test hence not declared static,
640 OicSecAcl_t* CBORPayloadToAcl(const uint8_t *cborPayload, const size_t size)
641 {
642     if (NULL == cborPayload || 0 == size)
643     {
644         return NULL;
645     }
646     OCStackResult ret = OC_STACK_ERROR;
647     CborValue aclCbor = { .parser = NULL };
648     CborParser parser = { .end = NULL };
649     CborError cborFindResult = CborNoError;
650     cbor_parser_init(cborPayload, size, 0, &parser, &aclCbor);
651
652     OicSecAcl_t *acl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
653
654     // Enter ACL Map
655     CborValue aclMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
656     cborFindResult = cbor_value_enter_container(&aclCbor, &aclMap);
657     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACL Map.");
658
659     while (cbor_value_is_valid(&aclMap))
660     {
661         char* tagName = NULL;
662         size_t len = 0;
663         CborType type = cbor_value_get_type(&aclMap);
664         if (type == CborTextStringType)
665         {
666             cborFindResult = cbor_value_dup_text_string(&aclMap, &tagName, &len, NULL);
667             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in ACL Map.");
668             cborFindResult = cbor_value_advance(&aclMap);
669             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in ACL Map.");
670         }
671         if(tagName)
672         {
673             if (strcmp(tagName, OIC_JSON_ACLIST_NAME)  == 0)
674             {
675                 // Enter ACLIST Map
676                 CborValue aclistMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
677                 cborFindResult = cbor_value_enter_container(&aclMap, &aclistMap);
678                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACLIST Map.");
679
680
681                 while (cbor_value_is_valid(&aclistMap))
682                 {
683                     char* acName = NULL;
684                     size_t readLen = 0;
685                     CborType acType = cbor_value_get_type(&aclistMap);
686                     if (acType == CborTextStringType)
687                     {
688                         cborFindResult = cbor_value_dup_text_string(&aclistMap, &acName, &readLen, NULL);
689                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in ACLIST Map.");
690                         cborFindResult = cbor_value_advance(&aclistMap);
691                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in ACLIST Map.");
692                     }
693
694                     if(acName)
695                     {
696                         if (strcmp(acName, OIC_JSON_ACES_NAME)  == 0)
697                         {
698                             // Enter ACES Array
699                             CborValue acesArray = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
700                             cborFindResult = cbor_value_enter_container(&aclistMap, &acesArray);
701                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACES Array.");
702
703                             int acesCount = 0;
704                             while (cbor_value_is_valid(&acesArray))
705                             {
706                                 acesCount++;
707                                 CborValue aceMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
708                                 cborFindResult = cbor_value_enter_container(&acesArray, &aceMap);
709                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACE Map.");
710
711                                 OicSecAce_t *ace = NULL;
712                                 ace = (OicSecAce_t *) OICCalloc(1, sizeof(OicSecAce_t));
713                                 VERIFY_NON_NULL(TAG, ace, ERROR);
714                                 LL_APPEND(acl->aces, ace);
715
716                                 VERIFY_NON_NULL(TAG, acl, ERROR);
717
718                                 while (cbor_value_is_valid(&aceMap))
719                                 {
720                                     char* name = NULL;
721                                     size_t len = 0;
722                                     CborType type = cbor_value_get_type(&aceMap);
723                                     if (type == CborTextStringType)
724                                     {
725                                         cborFindResult = cbor_value_dup_text_string(&aceMap, &name, &len, NULL);
726                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in ACE Map.");
727                                         cborFindResult = cbor_value_advance(&aceMap);
728                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in ACE Map.");
729                                     }
730                                     if (name)
731                                     {
732                                         // Subject -- Mandatory
733                                         if (strcmp(name, OIC_JSON_SUBJECTID_NAME)  == 0)
734                                         {
735                                             char *subject = NULL;
736                                             cborFindResult = cbor_value_dup_text_string(&aceMap, &subject, &len, NULL);
737                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding subject Value.");
738                                             if(strcmp(subject, WILDCARD_RESOURCE_URI) == 0)
739                                             {
740                                                 ace->subjectuuid.id[0] = '*';
741                                             }
742                                             else
743                                             {
744                                                 ret = ConvertStrToUuid(subject, &ace->subjectuuid);
745                                                 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
746                                             }
747                                             OICFree(subject);
748                                         }
749
750                                         // Resources -- Mandatory
751                                         if (strcmp(name, OIC_JSON_RESOURCES_NAME) == 0)
752                                         {
753                                             CborValue resources = { .parser = NULL };
754                                             cborFindResult = cbor_value_enter_container(&aceMap, &resources);
755                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering a Resource Array.");
756
757                                             while (cbor_value_is_valid(&resources))
758                                             {
759                                                 // rMap
760                                                 CborValue rMap = { .parser = NULL  };
761                                                 cborFindResult = cbor_value_enter_container(&resources, &rMap);
762                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering Resource Map");
763
764                                                 OicSecRsrc_t* rsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
765                                                 VERIFY_NON_NULL(TAG, rsrc, ERROR);
766                                                 LL_APPEND(ace->resources, rsrc);
767
768                                                 while(cbor_value_is_valid(&rMap))
769                                                 {
770                                                     char *rMapName = NULL;
771                                                     size_t rMapNameLen = 0;
772                                                     cborFindResult = cbor_value_dup_text_string(&rMap, &rMapName, &rMapNameLen, NULL);
773                                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Name Tag.");
774                                                     cborFindResult = cbor_value_advance(&rMap);
775                                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Value.");
776
777                                                     // "href"
778                                                     if (0 == strcmp(OIC_JSON_HREF_NAME, rMapName))
779                                                     {
780                                                         cborFindResult = cbor_value_dup_text_string(&rMap, &rsrc->href, &len, NULL);
781                                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Href Value.");
782                                                     }
783
784                                                     // "rt"
785                                                     if (0 == strcmp(OIC_JSON_RT_NAME, rMapName) && cbor_value_is_array(&rMap))
786                                                     {
787                                                         cbor_value_get_array_length(&rMap, &rsrc->typeLen);
788                                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RT array length.");
789                                                         VERIFY_SUCCESS(TAG, (0 != rsrc->typeLen), ERROR);
790
791                                                         rsrc->types = (char**)OICCalloc(rsrc->typeLen, sizeof(char*));
792                                                         VERIFY_NON_NULL(TAG, rsrc->types, ERROR);
793
794                                                         CborValue resourceTypes;
795                                                         cborFindResult = cbor_value_enter_container(&rMap, &resourceTypes);
796                                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering RT Array.");
797
798                                                         for(size_t i = 0; cbor_value_is_valid(&resourceTypes) && cbor_value_is_text_string(&resourceTypes); i++)
799                                                         {
800                                                             cborFindResult = cbor_value_dup_text_string(&resourceTypes, &(rsrc->types[i]), &readLen, NULL);
801                                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding resource type.");
802                                                             cborFindResult = cbor_value_advance(&resourceTypes);
803                                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing resource type.");
804                                                         }
805                                                     }
806
807                                                     // "if"
808                                                     if (0 == strcmp(OIC_JSON_IF_NAME, rMapName) && cbor_value_is_array(&rMap))
809                                                     {
810                                                         cbor_value_get_array_length(&rMap, &rsrc->interfaceLen);
811                                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding IF array length.");
812                                                         VERIFY_SUCCESS(TAG, (0 != rsrc->interfaceLen), ERROR);
813
814                                                         rsrc->interfaces = (char**)OICCalloc(rsrc->interfaceLen, sizeof(char*));
815                                                         VERIFY_NON_NULL(TAG, rsrc->interfaces, ERROR);
816
817                                                         CborValue interfaces;
818                                                         cborFindResult = cbor_value_enter_container(&rMap, &interfaces);
819                                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering IF Array.");
820
821                                                         for(size_t i = 0; cbor_value_is_valid(&interfaces) && cbor_value_is_text_string(&interfaces); i++)
822                                                         {
823                                                             cborFindResult = cbor_value_dup_text_string(&interfaces, &(rsrc->interfaces[i]), &readLen, NULL);
824                                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding IF type.");
825                                                             cborFindResult = cbor_value_advance(&interfaces);
826                                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing IF type.");
827                                                         }
828                                                     }
829
830                                                     // "rel"
831                                                     if (0 == strcmp(OIC_JSON_REL_NAME, rMapName))
832                                                     {
833                                                         cborFindResult = cbor_value_dup_text_string(&rMap, &rsrc->rel, &len, NULL);
834                                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding REL Value.");
835                                                     }
836
837                                                     if (cbor_value_is_valid(&rMap))
838                                                     {
839                                                         cborFindResult = cbor_value_advance(&rMap);
840                                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Rlist Map.");
841                                                     }
842                                                     OICFree(rMapName);
843                                                 }
844
845                                                 if (cbor_value_is_valid(&resources))
846                                                 {
847                                                     cborFindResult = cbor_value_advance(&resources);
848                                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Resource Array.");
849                                                 }
850                                             }
851                                         }
852
853                                         // Permissions -- Mandatory
854                                         if (strcmp(name, OIC_JSON_PERMISSION_NAME) == 0)
855                                         {
856                                             uint64_t tmp64;
857                                             cborFindResult = cbor_value_get_uint64(&aceMap, &tmp64);
858                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a PERM Value.");
859                                             ace->permission = (uint16_t)tmp64;
860                                         }
861
862                                         // TODO: Need to verfication for validity
863                                         // Validity -- Not mandatory
864                                         if(strcmp(name, OIC_JSON_VALIDITY_NAME) == 0)
865                                         {
866                                             CborValue validitiesMap = {.parser = NULL};
867                                             size_t validitySize = 0;
868
869                                             cborFindResult = cbor_value_get_array_length(&aceMap, &validitySize);
870                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a Validity Array Length.");
871
872                                             cborFindResult = cbor_value_enter_container(&aceMap, &validitiesMap);
873                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a validity Array Map.");
874
875                                             while(cbor_value_is_valid(&validitiesMap))
876                                             {
877                                                 OicSecValidity_t* validity = (OicSecValidity_t*)OICCalloc(1, sizeof(OicSecValidity_t));
878                                                 VERIFY_NON_NULL(TAG, validity, ERROR);
879                                                 LL_APPEND(ace->validities, validity);
880
881                                                 CborValue validityMap  = {.parser = NULL};
882                                                 //period (string)
883                                                 cborFindResult = cbor_value_enter_container(&validitiesMap, &validityMap);
884                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a validity Map.");
885
886                                                 size_t len = 0;
887                                                 cborFindResult =cbor_value_dup_text_string(&validityMap, &validity->period, &len, NULL);
888                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a Period value.");
889
890                                                 //recurrence (string array)
891                                                 CborValue recurrenceMap  = {.parser = NULL};
892                                                 cborFindResult = cbor_value_enter_container(&validityMap, &recurrenceMap);
893                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a recurrence array.");
894
895                                                 cborFindResult = cbor_value_get_array_length(&recurrenceMap, &validity->recurrenceLen);
896                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Adding Recurrence Array.");
897
898                                                 validity->recurrences = (char**)OICCalloc(validity->recurrenceLen, sizeof(char*));
899                                                 VERIFY_NON_NULL(TAG, validity->recurrences, ERROR);
900
901                                                 for(size_t i = 0; cbor_value_is_text_string(&recurrenceMap) && i < validity->recurrenceLen; i++)
902                                                 {
903                                                     cborFindResult = cbor_value_dup_text_string(&recurrenceMap, &validity->recurrences[i], &len, NULL);
904                                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a recurrence Value.");
905
906                                                     cborFindResult = cbor_value_advance(&recurrenceMap);
907                                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing a recurrences Array.");
908                                                 }
909
910                                                 cborFindResult = cbor_value_advance(&validitiesMap);
911                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing a validities Array.");
912                                             }
913                                         }
914                                         OICFree(name);
915                                     }
916
917                                     if (type != CborMapType && cbor_value_is_valid(&aceMap))
918                                     {
919                                         cborFindResult = cbor_value_advance(&aceMap);
920                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing the Array.");
921                                     }
922                                 }
923
924                                 if (cbor_value_is_valid(&acesArray))
925                                 {
926                                     cborFindResult = cbor_value_advance(&acesArray);
927                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing ACL Array.");
928                                 }
929                             }
930                         }
931                         OICFree(acName);
932                     }
933
934                     if (cbor_value_is_valid(&aclistMap))
935                     {
936                         cborFindResult = cbor_value_advance(&aclistMap);
937                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing ACLIST Map.");
938                     }
939                 }
940             }
941
942             //rownerID -- Mandatory
943             if (strcmp(tagName, OIC_JSON_ROWNERID_NAME)  == 0)
944             {
945                 char *stRowner = NULL;
946                 cborFindResult = cbor_value_dup_text_string(&aclMap, &stRowner, &len, NULL);
947                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Rownerid Value.");
948                 ret = ConvertStrToUuid(stRowner, &acl->rownerID);
949                 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
950                 OICFree(stRowner);
951             }
952             OICFree(tagName);
953         }
954         if (cbor_value_is_valid(&aclMap))
955         {
956             cborFindResult = cbor_value_advance(&aclMap);
957             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing ACL Map.");
958         }
959     }
960
961 exit:
962     if (cborFindResult != CborNoError)
963     {
964         OIC_LOG(ERROR, TAG, "Failed to CBORPayloadToAcl");
965         DeleteACLList(acl);
966         acl = NULL;
967     }
968
969     return acl;
970 }
971
972 /**
973  * This method removes ACE for the subject and resource from the ACL
974  *
975  * @param subject of the ACE
976  * @param resource of the ACE
977  *
978  * @return
979  *     ::OC_STACK_RESOURCE_DELETED on success
980  *     ::OC_STACK_NO_RESOURCE on failure to find the appropriate ACE
981  *     ::OC_STACK_INVALID_PARAM on invalid parameter
982  */
983 OCStackResult RemoveACE(const OicUuid_t * subject, const char * resource)
984 {
985     OIC_LOG(DEBUG, TAG, "IN RemoveACE");
986
987     OicSecAce_t *ace = NULL;
988     OicSecAce_t *tempAce = NULL;
989     bool deleteFlag = false;
990     OCStackResult ret = OC_STACK_NO_RESOURCE;
991
992     if (memcmp(subject->id, &WILDCARD_SUBJECT_ID, sizeof(subject->id)) == 0)
993     {
994         OIC_LOG_V(ERROR, TAG, "%s received invalid parameter", __func__ );
995         return  OC_STACK_INVALID_PARAM;
996     }
997
998     //If resource is NULL then delete all the ACE for the subject.
999     if (NULL == resource || resource[0] == '\0')
1000     {
1001         LL_FOREACH_SAFE(gAcl->aces, ace, tempAce)
1002         {
1003             if (memcmp(ace->subjectuuid.id, subject->id, sizeof(subject->id)) == 0)
1004             {
1005                 LL_DELETE(gAcl->aces, ace);
1006                 FreeACE(ace);
1007                 deleteFlag = true;
1008             }
1009         }
1010     }
1011     else
1012     {
1013         //Looping through ACL to find the right ACE to delete. If the required resource is the only
1014         //resource in the ACE for the subject then delete the whole ACE. If there are more resources
1015         //than the required resource in the ACE, for the subject then just delete the resource from
1016         //the resource array
1017         LL_FOREACH_SAFE(gAcl->aces, ace, tempAce)
1018         {
1019             if (memcmp(ace->subjectuuid.id, subject->id, sizeof(subject->id)) == 0)
1020             {
1021                 OicSecRsrc_t* rsrc = NULL;
1022                 OicSecRsrc_t* tempRsrc = NULL;
1023                 LL_FOREACH_SAFE(ace->resources, rsrc, tempRsrc)
1024                 {
1025                     if(strcmp(rsrc->href, resource) == 0)
1026                     {
1027                         LL_DELETE(ace->resources, rsrc);
1028                         FreeRsrc(rsrc);
1029                         deleteFlag = true;
1030                     }
1031                 }
1032
1033                 //If resource list is empty
1034                 if(NULL == ace->resources && true == deleteFlag)
1035                 {
1036                     //Remove the ACE from ACL
1037                     LL_DELETE(gAcl->aces, ace);
1038                     FreeACE(ace);
1039                 }
1040             }
1041         }
1042     }
1043
1044     if (deleteFlag)
1045     {
1046         // In case of unit test do not update persistant storage.
1047         if (memcmp(subject->id, &WILDCARD_SUBJECT_B64_ID, sizeof(subject->id)) == 0)
1048         {
1049             ret = OC_STACK_RESOURCE_DELETED;
1050         }
1051         else
1052         {
1053             uint8_t *payload = NULL;
1054             size_t size = 0;
1055             if (OC_STACK_OK == AclToCBORPayload(gAcl, &payload, &size))
1056             {
1057                 if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, payload, size))
1058                 {
1059                     ret = OC_STACK_RESOURCE_DELETED;
1060                 }
1061                 OICFree(payload);
1062             }
1063         }
1064     }
1065     return ret;
1066 }
1067
1068 /**
1069  * This method parses the query string received for REST requests and
1070  * retrieves the 'subject' field.
1071  *
1072  * @param query querystring passed in REST request
1073  * @param subject subject UUID parsed from query string
1074  *
1075  * @return true if query parsed successfully and found 'subject', else false.
1076  */
1077 static bool GetSubjectFromQueryString(const char *query, OicUuid_t *subject)
1078 {
1079     OicParseQueryIter_t parseIter = { .attrPos = NULL };
1080
1081     ParseQueryIterInit((unsigned char *) query, &parseIter);
1082
1083     while (GetNextQuery (&parseIter))
1084     {
1085         if (strncasecmp((char *) parseIter.attrPos, OIC_JSON_SUBJECTID_NAME, parseIter.attrLen) == 0)
1086         {
1087             char strUuid[STRING_UUID_SIZE] = {0};
1088             VERIFY_SUCCESS(TAG, 0 != parseIter.valLen, ERROR);
1089             memcpy(strUuid, parseIter.valPos, parseIter.valLen);
1090             OCStackResult res = ConvertStrToUuid(strUuid, subject);
1091             VERIFY_SUCCESS(TAG, OC_STACK_OK == res, ERROR);
1092             return true;
1093         }
1094     }
1095
1096 exit:
1097     return false;
1098 }
1099
1100 /**
1101  * This method parses the query string received for REST requests and
1102  * retrieves the 'resource' field.
1103  *
1104  * @param query querystring passed in REST request
1105  * @param resource resource parsed from query string
1106  * @param resourceSize size of the memory pointed to resource
1107  *
1108  * @return true if query parsed successfully and found 'resource', else false.
1109  */
1110 static bool GetResourceFromQueryString(const char *query, char *resource, size_t resourceSize)
1111 {
1112     OicParseQueryIter_t parseIter = { .attrPos = NULL };
1113
1114     ParseQueryIterInit((unsigned char *) query, &parseIter);
1115
1116     while (GetNextQuery (&parseIter))
1117     {
1118         if (strncasecmp((char *) parseIter.attrPos, OIC_JSON_RESOURCES_NAME, parseIter.attrLen)
1119                 == 0)
1120         {
1121             VERIFY_SUCCESS(TAG, 0 != parseIter.valLen, ERROR);
1122             OICStrcpy(resource, resourceSize, (char *) parseIter.valPos);
1123
1124             return true;
1125         }
1126     }
1127
1128 exit:
1129    return false;
1130 }
1131
1132 static size_t GetNumberOfResource(OicSecRsrc_t* resources)
1133 {
1134     size_t ret = 0;
1135     if(resources)
1136     {
1137         OicSecRsrc_t* rsrc = NULL;
1138         LL_FOREACH(resources, rsrc)
1139         {
1140             ret++;
1141         }
1142     }
1143     return ret;
1144 }
1145
1146 static size_t GetNumberOfValidity(OicSecValidity_t* val)
1147 {
1148     size_t ret = 0;
1149
1150     if(val)
1151     {
1152         OicSecValidity_t* temp = NULL;
1153         LL_FOREACH(val, temp)
1154         {
1155             ret++;
1156         }
1157     }
1158     return ret;
1159 }
1160
1161
1162 static bool IsSameStringArray(char** strArr1, size_t strArr1Len,
1163                               char** strArr2, size_t strArr2Len)
1164 {
1165
1166     if(NULL == strArr1 && NULL == strArr2)
1167     {
1168         return true;
1169     }
1170
1171     if(strArr1 && strArr2 && NULL == *strArr1 && NULL == *strArr2)
1172     {
1173         return true;
1174     }
1175
1176     if(strArr1 && strArr2)
1177     {
1178         if(*strArr1 && *strArr2 && strArr1Len == strArr2Len)
1179         {
1180             size_t matchedStr = 0;
1181             for(size_t i = 0; i < strArr1Len; i++)
1182             {
1183                 for(size_t j = 0; j < strArr2Len; j++)
1184                 {
1185                     if(strcmp(strArr1[i], strArr2[j]) == 0)
1186                     {
1187                         matchedStr++;
1188                     }
1189                 }
1190             }
1191             if(matchedStr == strArr1Len)
1192             {
1193                 return true;
1194             }
1195         }
1196     }
1197
1198     return false;
1199 }
1200
1201 static bool IsSameResources(OicSecRsrc_t* resources1, OicSecRsrc_t* resources2)
1202 {
1203     size_t numOfRsrc1 = 0;
1204     size_t numOfRsrc2 = 0;
1205     size_t numOfMatchedRsrc = 0;
1206     OicSecRsrc_t* rsrc1 = NULL;
1207     OicSecRsrc_t* rsrc2 = NULL;
1208
1209     if(NULL == resources1 && NULL == resources2)
1210     {
1211         return true;
1212     }
1213
1214     if(resources1 && resources2)
1215     {
1216         numOfRsrc1 = GetNumberOfResource(resources1);
1217         numOfRsrc2 = GetNumberOfResource(resources2);
1218
1219         if(0 == numOfRsrc1 && 0 == numOfRsrc2)
1220         {
1221             return true;
1222         }
1223
1224         LL_FOREACH(resources1, rsrc1)
1225         {
1226             rsrc2 = NULL;
1227             LL_FOREACH(resources2, rsrc2)
1228             {
1229                 if(rsrc1 && rsrc2)
1230                 {
1231                     if(strcmp(rsrc1->href, rsrc2->href) == 0 &&
1232                         IsSameStringArray(rsrc1->interfaces, rsrc1->interfaceLen,
1233                                           rsrc2->interfaces, rsrc2->interfaceLen) &&
1234                         IsSameStringArray(rsrc1->types, rsrc1->typeLen,
1235                                           rsrc2->types, rsrc2->typeLen))
1236                     {
1237                         // TODO: Update codes to compare 'rel' property
1238                         numOfMatchedRsrc++;
1239                     }
1240                 }
1241             }
1242         }
1243
1244         if(numOfMatchedRsrc == numOfRsrc1)
1245         {
1246             return true;
1247         }
1248     }
1249
1250     return false;
1251 }
1252
1253 static bool IsSameValidities(OicSecValidity_t* validities1, OicSecValidity_t* validities2)
1254 {
1255     size_t numOfVal1 = 0;
1256     size_t numOfVal2 = 0;
1257     size_t numOfMatchedVal = 0;
1258     OicSecValidity_t* val1 = NULL;
1259     OicSecValidity_t* val2 = NULL;
1260
1261     if(NULL == validities1 && NULL == validities2)
1262     {
1263         return true;
1264     }
1265
1266     if(validities1 && validities2)
1267     {
1268         numOfVal1 = GetNumberOfValidity(validities1);
1269         numOfVal2 = GetNumberOfValidity(validities2);
1270         if(0 == numOfVal1 && 0 == numOfVal2)
1271         {
1272             return true;
1273         }
1274
1275         if(numOfVal1 == numOfVal2)
1276         {
1277             LL_FOREACH(validities1, val1)
1278             {
1279                 LL_FOREACH(validities2, val2)
1280                 {
1281                     if(strcmp(val1->period, val2->period) == 0 &&
1282                         IsSameStringArray(val1->recurrences, val1->recurrenceLen,
1283                                           val2->recurrences, val2->recurrenceLen))
1284                     {
1285                         numOfMatchedVal++;
1286                     }
1287                 }
1288             }
1289             if(numOfVal1 == numOfMatchedVal)
1290             {
1291                 return true;
1292             }
1293         }
1294     }
1295
1296     return false;
1297 }
1298
1299 static bool IsSameACE(OicSecAce_t* ace1, OicSecAce_t* ace2)
1300 {
1301     if(ace1 && ace2)
1302     {
1303         if(memcmp(ace1->subjectuuid.id, ace2->subjectuuid.id, sizeof(ace1->subjectuuid.id)) != 0)
1304         {
1305             return false;
1306         }
1307
1308         if(false == IsSameResources(ace1->resources, ace2->resources))
1309         {
1310             return false;
1311         }
1312
1313         if(ace1->permission != ace2->permission)
1314         {
1315             return false;
1316         }
1317
1318         if(false == IsSameValidities(ace1->validities, ace2->validities))
1319         {
1320             return false;
1321         }
1322
1323         return true;
1324     }
1325
1326     return false;
1327 }
1328
1329 static OCEntityHandlerResult HandleACLGetRequest(const OCEntityHandlerRequest *ehRequest)
1330 {
1331     OIC_LOG(INFO, TAG, "HandleACLGetRequest processing the request");
1332     uint8_t* payload = NULL;
1333     size_t size = 0;
1334     OCEntityHandlerResult ehRet;
1335
1336     OicUuid_t subject = {.id= { 0 } };
1337
1338     // In case, 'subject' field is included in REST request.
1339     if (ehRequest->query && GetSubjectFromQueryString(ehRequest->query, &subject))
1340     {
1341         OIC_LOG(DEBUG,TAG,"'subject' field is inculded in REST request.");
1342         OIC_LOG(DEBUG, TAG, "HandleACLGetRequest processing query");
1343
1344         char resource[MAX_URI_LENGTH] = { 0 };
1345
1346         OicSecAce_t *savePtr = NULL;
1347         const OicSecAce_t *currentAce = NULL;
1348         OicSecAcl_t targetAcl;
1349
1350         memcpy(&targetAcl.rownerID, &gAcl->rownerID, sizeof(OicUuid_t));
1351         targetAcl.aces = NULL;
1352
1353         // 'Subject' field is MUST for processing a querystring in REST request.
1354         GetResourceFromQueryString(ehRequest->query, resource, sizeof(resource));
1355
1356         /*
1357          * TODO : Currently, this code only provides one ACE for a Subject.
1358          * Below code needs to be updated for scenarios when Subject have
1359          * multiple ACE's in ACL resource.
1360          */
1361         while ((currentAce = GetACLResourceData(&subject, &savePtr)))
1362         {
1363             targetAcl.aces = (OicSecAce_t*)currentAce;
1364
1365             /*
1366              * If REST querystring contains a specific resource, we need
1367              * to search for that resource in ACE.
1368              */
1369             if (resource[0] != '\0')
1370             {
1371                 OicSecRsrc_t *rsrc = NULL;
1372                 LL_FOREACH(currentAce->resources, rsrc)
1373                 {
1374                     if(0 == strcmp(rsrc->href, resource) ||
1375                         0 == strcmp(WILDCARD_RESOURCE_URI, rsrc->href))
1376                     {
1377                         // Convert ACL data into CBOR format for transmission
1378                         if (OC_STACK_OK != AclToCBORPayload(&targetAcl, &payload, &size))
1379                         {
1380                             ehRet = OC_EH_ERROR;
1381                         }
1382                         goto exit;
1383                     }
1384                 }
1385             }
1386             else
1387             {
1388                 // Convert ACL data into CBOR format for transmission
1389                 if (OC_STACK_OK != AclToCBORPayload(&targetAcl, &payload, &size))
1390                 {
1391                     ehRet = OC_EH_ERROR;
1392                 }
1393                 goto exit;
1394             }
1395         }
1396     }
1397     // In case, 'subject' field is not included in REST request.
1398     else
1399     {
1400         OIC_LOG(DEBUG,TAG,"'subject' field is not inculded in REST request.");
1401         // Convert ACL data into CBOR format for transmission.
1402         if (OC_STACK_OK != AclToCBORPayload(gAcl, &payload, &size))
1403         {
1404             ehRet = OC_EH_ERROR;
1405         }
1406     }
1407 exit:
1408     // A device should always have a default acl. Therefore, payload should never be NULL.
1409     ehRet = (payload ? OC_EH_OK : OC_EH_ERROR);
1410     OIC_LOG(DEBUG, TAG, "ACL payload with GET response");
1411     OIC_LOG_BUFFER(DEBUG, TAG, payload, size);
1412
1413     //Send payload to request originator
1414     ehRet = ((SendSRMResponse(ehRequest, ehRet, payload, size)) == OC_STACK_OK) ?
1415                    OC_EH_OK : OC_EH_ERROR;
1416
1417     OICFree(payload);
1418
1419     OIC_LOG_V(DEBUG, TAG, "%s RetVal %d", __func__, ehRet);
1420     return ehRet;
1421 }
1422
1423 static OCEntityHandlerResult HandleACLPostRequest(const OCEntityHandlerRequest *ehRequest)
1424 {
1425     OIC_LOG(INFO, TAG, "HandleACLPostRequest processing the request");
1426     OCEntityHandlerResult ehRet = OC_EH_OK;
1427
1428     // Convert CBOR into ACL data and update to SVR buffers. This will also validate the ACL data received.
1429     uint8_t *payload = ((OCSecurityPayload *) ehRequest->payload)->securityData;
1430     size_t size = ((OCSecurityPayload *) ehRequest->payload)->payloadSize;
1431     if (payload)
1432     {
1433         OicSecAcl_t *newAcl = NULL;
1434         OicSecAcl_t newAceList;
1435         OIC_LOG(DEBUG, TAG, "ACL payload from POST request << ");
1436         OIC_LOG_BUFFER(DEBUG, TAG, payload, size);
1437
1438         newAcl = CBORPayloadToAcl(payload, size);
1439         if (newAcl)
1440         {
1441             bool isNewAce = true;
1442             OicSecAce_t* existAce = NULL;
1443             OicSecAce_t* newAce = NULL;
1444             OicSecAce_t* tempAce1 = NULL;
1445             OicSecAce_t* tempAce2 = NULL;
1446             newAceList.aces = NULL;
1447
1448             LL_FOREACH_SAFE(newAcl->aces, newAce, tempAce1)
1449             {
1450                 isNewAce = true;
1451                 LL_FOREACH_SAFE(gAcl->aces, existAce, tempAce2)
1452                 {
1453                     if(IsSameACE(newAce, existAce))
1454                     {
1455                         isNewAce = false;
1456                     }
1457                 }
1458                 if(isNewAce)
1459                 {
1460                     OIC_LOG(DEBUG, TAG, "NEW ACE dectected.");
1461
1462                     OicSecAce_t* insertAce = DuplicateACE(newAce);
1463                     if(insertAce)
1464                     {
1465                         OIC_LOG(DEBUG, TAG, "Appending new ACE..");
1466                         LL_PREPEND(gAcl->aces, insertAce);
1467                     }
1468                     else
1469                     {
1470                         OIC_LOG(ERROR, TAG, "Failed to duplicate ACE.");
1471                         ehRet = OC_EH_ERROR;
1472                     }
1473                 }
1474             }
1475
1476             DeleteACLList(newAcl);
1477
1478             if(OC_EH_OK == ehRet)
1479             {
1480                 size_t size = 0;
1481                 uint8_t *cborPayload = NULL;
1482                 if (OC_STACK_OK == AclToCBORPayload(gAcl, &cborPayload, &size))
1483                 {
1484                     if (UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, cborPayload, size) == OC_STACK_OK)
1485                     {
1486                         ehRet = OC_EH_CHANGED;
1487                     }
1488                     OICFree(cborPayload);
1489                 }
1490
1491                 if(OC_EH_CHANGED != ehRet)
1492                 {
1493                     ehRet = OC_EH_ERROR;
1494                 }
1495             }
1496         }
1497     }
1498
1499     //Send response to request originator
1500     ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
1501                    OC_EH_OK : OC_EH_ERROR;
1502
1503     OIC_LOG_V(DEBUG, TAG, "%s RetVal %d", __func__, ehRet);
1504     return ehRet;
1505 }
1506
1507 static OCEntityHandlerResult HandleACLDeleteRequest(const OCEntityHandlerRequest *ehRequest)
1508 {
1509     OIC_LOG(DEBUG, TAG, "Processing ACLDeleteRequest");
1510     OCEntityHandlerResult ehRet = OC_EH_ERROR;
1511     OicUuid_t subject = { .id= { 0 } };
1512     char resource[MAX_URI_LENGTH] = { 0 };
1513
1514     VERIFY_NON_NULL(TAG, ehRequest->query, ERROR);
1515
1516     // 'Subject' field is MUST for processing a querystring in REST request.
1517     VERIFY_SUCCESS(TAG, true == GetSubjectFromQueryString(ehRequest->query, &subject), ERROR);
1518
1519     GetResourceFromQueryString(ehRequest->query, resource, sizeof(resource));
1520
1521     if (OC_STACK_RESOURCE_DELETED == RemoveACE(&subject, resource))
1522     {
1523         ehRet = OC_EH_RESOURCE_DELETED;
1524     }
1525
1526 exit:
1527     //Send response to request originator
1528     ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
1529                    OC_EH_OK : OC_EH_ERROR;
1530
1531     return ehRet;
1532 }
1533
1534 OCEntityHandlerResult ACLEntityHandler(OCEntityHandlerFlag flag, OCEntityHandlerRequest * ehRequest,
1535         void* callbackParameter)
1536 {
1537     OIC_LOG(DEBUG, TAG, "Received request ACLEntityHandler");
1538     (void)callbackParameter;
1539     OCEntityHandlerResult ehRet = OC_EH_ERROR;
1540
1541     if (!ehRequest)
1542     {
1543         return ehRet;
1544     }
1545
1546     if (flag & OC_REQUEST_FLAG)
1547     {
1548         // TODO :  Handle PUT method
1549         OIC_LOG(DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
1550         switch (ehRequest->method)
1551         {
1552             case OC_REST_GET:
1553                 ehRet = HandleACLGetRequest(ehRequest);
1554                 break;
1555
1556             case OC_REST_POST:
1557                 ehRet = HandleACLPostRequest(ehRequest);
1558                 break;
1559
1560             case OC_REST_DELETE:
1561                 ehRet = HandleACLDeleteRequest(ehRequest);
1562                 break;
1563
1564             default:
1565                 ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
1566                                OC_EH_OK : OC_EH_ERROR;
1567         }
1568     }
1569
1570     return ehRet;
1571 }
1572
1573 /**
1574  * This internal method is used to create '/oic/sec/acl' resource.
1575  */
1576 static OCStackResult CreateACLResource()
1577 {
1578     OCStackResult ret;
1579
1580     ret = OCCreateResource(&gAclHandle,
1581                            OIC_RSRC_TYPE_SEC_ACL,
1582                            OC_RSRVD_INTERFACE_DEFAULT,
1583                            OIC_RSRC_ACL_URI,
1584                            ACLEntityHandler,
1585                            NULL,
1586                            OC_OBSERVABLE | OC_SECURE | OC_EXPLICIT_DISCOVERABLE);
1587
1588     if (OC_STACK_OK != ret)
1589     {
1590         OIC_LOG(FATAL, TAG, "Unable to instantiate ACL resource");
1591         DeInitACLResource();
1592     }
1593     return ret;
1594 }
1595
1596 // This function sets the default ACL and is defined for the unit test only.
1597 OCStackResult SetDefaultACL(OicSecAcl_t *acl)
1598 {
1599     gAcl = acl;
1600     return OC_STACK_OK;
1601 }
1602
1603 OCStackResult GetDefaultACL(OicSecAcl_t** defaultAcl)
1604 {
1605     OCStackResult ret = OC_STACK_ERROR;
1606     OicUuid_t ownerId = { .id = { 0 } };
1607     OicSecAcl_t *acl = NULL;
1608     OicSecAce_t *ace = NULL;
1609     OicSecRsrc_t* resRsrc = NULL;
1610     OicSecRsrc_t* deviceRsrc = NULL;
1611     OicSecRsrc_t* platformRsrc = NULL;
1612     OicSecRsrc_t* aclRsrc = NULL;
1613     OicSecRsrc_t* doxmRsrc = NULL;
1614     OicSecRsrc_t* pstatRsrc = NULL;
1615
1616     /*
1617      * TODO In future, when new virtual resources will be added in OIC
1618      * specification, Iotivity stack should be able to add them in
1619      * existing SVR database. To support this, we need to add 'versioning'
1620      * mechanism in SVR database.
1621      */
1622
1623     if (!defaultAcl)
1624     {
1625         return OC_STACK_INVALID_PARAM;
1626     }
1627
1628     acl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
1629     VERIFY_NON_NULL(TAG, acl, ERROR);
1630
1631     ace = (OicSecAce_t *) OICCalloc(1, sizeof(OicSecAce_t));
1632     VERIFY_NON_NULL(TAG, ace, ERROR);
1633
1634     LL_APPEND(acl->aces, ace);
1635
1636     // Subject -- Mandatory
1637     memcpy(ace->subjectuuid.id, &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t));
1638
1639     // Resources -- Mandatory
1640     // /oic/res
1641     resRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1642     VERIFY_NON_NULL(TAG, resRsrc, ERROR);
1643     LL_APPEND(ace->resources, resRsrc);
1644     resRsrc->href = OICStrdup(OC_RSRVD_WELL_KNOWN_URI);
1645     VERIFY_NON_NULL(TAG, (resRsrc->href), ERROR);
1646     resRsrc->typeLen = 1;
1647     resRsrc->types = (char**)OICCalloc(1, sizeof(char*));
1648     VERIFY_NON_NULL(TAG, resRsrc->types, ERROR);
1649     resRsrc->types[0] = OICStrdup(OC_RSRVD_RESOURCE_TYPE_RES);
1650     VERIFY_NON_NULL(TAG, resRsrc->types[0], ERROR);
1651     resRsrc->interfaceLen = 2;
1652     resRsrc->interfaces = (char**)OICCalloc(resRsrc->interfaceLen, sizeof(char*));
1653     VERIFY_NON_NULL(TAG, resRsrc->interfaces, ERROR);
1654     resRsrc->interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
1655     VERIFY_NON_NULL(TAG, resRsrc->interfaces[0], ERROR);
1656     resRsrc->interfaces[1] = OICStrdup(OC_RSRVD_INTERFACE_READ);
1657     VERIFY_NON_NULL(TAG, resRsrc->interfaces[1], ERROR);
1658
1659     // /oic/d
1660     deviceRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1661     VERIFY_NON_NULL(TAG, deviceRsrc, ERROR);
1662     LL_APPEND(ace->resources, deviceRsrc);
1663     deviceRsrc->href = OICStrdup(OC_RSRVD_DEVICE_URI);
1664     VERIFY_NON_NULL(TAG, (deviceRsrc->href), ERROR);
1665     deviceRsrc->typeLen = 1;
1666     deviceRsrc->types = (char**)OICCalloc(1, sizeof(char*));
1667     VERIFY_NON_NULL(TAG, deviceRsrc->types, ERROR);
1668     deviceRsrc->types[0] = OICStrdup(OC_RSRVD_RESOURCE_TYPE_DEVICE);
1669     VERIFY_NON_NULL(TAG, deviceRsrc->types[0], ERROR);
1670     deviceRsrc->interfaceLen = 2;
1671     deviceRsrc->interfaces = (char**)OICCalloc(deviceRsrc->interfaceLen, sizeof(char*));
1672     VERIFY_NON_NULL(TAG, deviceRsrc->interfaces, ERROR);
1673     deviceRsrc->interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
1674     VERIFY_NON_NULL(TAG, deviceRsrc->interfaces[0], ERROR);
1675     deviceRsrc->interfaces[1] = OICStrdup(OC_RSRVD_INTERFACE_READ);
1676     VERIFY_NON_NULL(TAG, deviceRsrc->interfaces[1], ERROR);
1677
1678     // /oic/p
1679     platformRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1680     VERIFY_NON_NULL(TAG, platformRsrc, ERROR);
1681     LL_APPEND(ace->resources, platformRsrc);
1682     platformRsrc->href = OICStrdup(OC_RSRVD_PLATFORM_URI);
1683     VERIFY_NON_NULL(TAG, (platformRsrc->href), ERROR);
1684     platformRsrc->typeLen = 1;
1685     platformRsrc->types = (char**)OICCalloc(1, sizeof(char*));
1686     VERIFY_NON_NULL(TAG, platformRsrc->types, ERROR);
1687     platformRsrc->types[0] = OICStrdup(OC_RSRVD_RESOURCE_TYPE_PLATFORM);
1688     VERIFY_NON_NULL(TAG, platformRsrc->types[0], ERROR);
1689     platformRsrc->interfaceLen = 2;
1690     platformRsrc->interfaces = (char**)OICCalloc(platformRsrc->interfaceLen, sizeof(char*));
1691     VERIFY_NON_NULL(TAG, platformRsrc->interfaces, ERROR);
1692     platformRsrc->interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
1693     VERIFY_NON_NULL(TAG, platformRsrc->interfaces[0], ERROR);
1694     platformRsrc->interfaces[1] = OICStrdup(OC_RSRVD_INTERFACE_READ);
1695     VERIFY_NON_NULL(TAG, platformRsrc->interfaces[1], ERROR);
1696
1697     // /oic/sec/acl
1698     aclRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1699     VERIFY_NON_NULL(TAG, aclRsrc, ERROR);
1700     LL_APPEND(ace->resources, aclRsrc);
1701     aclRsrc->href = OICStrdup(OIC_RSRC_ACL_URI);
1702     VERIFY_NON_NULL(TAG, (aclRsrc->href), ERROR);
1703     aclRsrc->typeLen = 1;
1704     aclRsrc->types = (char**)OICCalloc(1, sizeof(char*));
1705     VERIFY_NON_NULL(TAG, aclRsrc->types, ERROR);
1706     aclRsrc->types[0] = OICStrdup(OIC_RSRC_TYPE_SEC_ACL);
1707     VERIFY_NON_NULL(TAG, aclRsrc->types[0], ERROR);
1708     aclRsrc->interfaceLen = 1;
1709     aclRsrc->interfaces = (char**)OICCalloc(aclRsrc->interfaceLen, sizeof(char*));
1710     VERIFY_NON_NULL(TAG, aclRsrc->interfaces, ERROR);
1711     aclRsrc->interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
1712     VERIFY_NON_NULL(TAG, aclRsrc->interfaces[0], ERROR);
1713
1714     // /oic/sec/doxm
1715     doxmRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1716     VERIFY_NON_NULL(TAG, doxmRsrc, ERROR);
1717     LL_APPEND(ace->resources, doxmRsrc);
1718     doxmRsrc->href = OICStrdup(OIC_RSRC_DOXM_URI);
1719     VERIFY_NON_NULL(TAG, (doxmRsrc->href), ERROR);
1720     doxmRsrc->typeLen = 1;
1721     doxmRsrc->types = (char**)OICCalloc(1, sizeof(char*));
1722     VERIFY_NON_NULL(TAG, doxmRsrc->types, ERROR);
1723     doxmRsrc->types[0] = OICStrdup(OIC_RSRC_TYPE_SEC_DOXM);
1724     VERIFY_NON_NULL(TAG, doxmRsrc->types[0], ERROR);
1725     doxmRsrc->interfaceLen = 1;
1726     doxmRsrc->interfaces = (char**)OICCalloc(doxmRsrc->interfaceLen, sizeof(char*));
1727     VERIFY_NON_NULL(TAG, doxmRsrc->interfaces, ERROR);
1728     doxmRsrc->interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
1729     VERIFY_NON_NULL(TAG, doxmRsrc->interfaces[0], ERROR);
1730
1731     // /oic/sec/pstat
1732     pstatRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1733     VERIFY_NON_NULL(TAG, pstatRsrc, ERROR);
1734     LL_APPEND(ace->resources, pstatRsrc);
1735     pstatRsrc->href = OICStrdup(OIC_RSRC_PSTAT_URI);
1736     VERIFY_NON_NULL(TAG, (pstatRsrc->href), ERROR);
1737     pstatRsrc->typeLen = 1;
1738     pstatRsrc->types = (char**)OICCalloc(1, sizeof(char*));
1739     VERIFY_NON_NULL(TAG, pstatRsrc->types, ERROR);
1740     pstatRsrc->types[0] = OICStrdup(OIC_RSRC_TYPE_SEC_PSTAT);
1741     VERIFY_NON_NULL(TAG, pstatRsrc->types[0], ERROR);
1742     pstatRsrc->interfaceLen = 1;
1743     pstatRsrc->interfaces = (char**)OICCalloc(pstatRsrc->interfaceLen, sizeof(char*));
1744     VERIFY_NON_NULL(TAG, pstatRsrc->interfaces, ERROR);
1745     pstatRsrc->interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
1746     VERIFY_NON_NULL(TAG, pstatRsrc->interfaces[0], ERROR);
1747
1748     ace->permission = PERMISSION_READ;
1749     ace->validities = NULL;
1750
1751     // Device ID is the owner of this default ACL
1752     if (GetDoxmResourceData() != NULL)
1753     {
1754         ret = GetDoxmDeviceID(&ownerId);
1755         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, FATAL);
1756     }
1757     else
1758     {
1759         OCRandomUuidResult rdm = OCGenerateUuid(ownerId.id);
1760         VERIFY_SUCCESS(TAG, RAND_UUID_OK == rdm, FATAL);
1761     }
1762
1763     memcpy(&acl->rownerID, &ownerId, sizeof(OicUuid_t));
1764
1765     *defaultAcl = acl;
1766     ret = OC_STACK_OK;
1767
1768 exit:
1769
1770     if (ret != OC_STACK_OK)
1771     {
1772         DeleteACLList(acl);
1773         acl = NULL;
1774     }
1775
1776     return ret;
1777 }
1778
1779 OCStackResult InitACLResource()
1780 {
1781     OCStackResult ret = OC_STACK_ERROR;
1782
1783     uint8_t *data = NULL;
1784     size_t size = 0;
1785     ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_ACL_NAME, &data, &size);
1786     // If database read failed
1787     if (OC_STACK_OK != ret)
1788     {
1789         OIC_LOG(DEBUG, TAG, "ReadSVDataFromPS failed");
1790     }
1791     if (data)
1792     {
1793         // Read ACL resource from PS
1794         gAcl = CBORPayloadToAcl(data, size);
1795     }
1796     /*
1797      * If SVR database in persistent storage got corrupted or
1798      * is not available for some reason, a default ACL is created
1799      * which allows user to initiate ACL provisioning again.
1800      */
1801     if (!gAcl)
1802     {
1803         ret = GetDefaultACL(&gAcl);
1804         if (OC_STACK_OK != ret)
1805         {
1806             OIC_LOG(ERROR, TAG, "Failed to create default ACL");
1807         }
1808         // TODO Needs to update persistent storage
1809     }
1810     VERIFY_NON_NULL(TAG, gAcl, FATAL);
1811
1812     // Instantiate 'oic.sec.acl'
1813     ret = CreateACLResource();
1814
1815 exit:
1816     if (OC_STACK_OK != ret)
1817     {
1818         DeInitACLResource();
1819     }
1820     return ret;
1821 }
1822
1823 OCStackResult DeInitACLResource()
1824 {
1825     OCStackResult ret =  OCDeleteResource(gAclHandle);
1826     gAclHandle = NULL;
1827
1828     if (gAcl)
1829     {
1830         DeleteACLList(gAcl);
1831         gAcl = NULL;
1832     }
1833     return ret;
1834 }
1835
1836 const OicSecAce_t* GetACLResourceData(const OicUuid_t* subjectId, OicSecAce_t **savePtr)
1837 {
1838     OicSecAce_t *ace = NULL;
1839     OicSecAce_t *begin = NULL;
1840
1841     if (NULL == subjectId)
1842     {
1843         return NULL;
1844     }
1845
1846     /*
1847      * savePtr MUST point to NULL if this is the 'first' call to retrieve ACL for
1848      * subjectID.
1849      */
1850     if (NULL == *savePtr)
1851     {
1852         begin = gAcl->aces;
1853     }
1854     else
1855     {
1856         /*
1857          * If this is a 'successive' call, search for location pointed by
1858          * savePtr and assign 'begin' to the next ACL after it in the linked
1859          * list and start searching from there.
1860          */
1861         LL_FOREACH(gAcl->aces, ace)
1862         {
1863             if (ace == *savePtr)
1864             {
1865                 begin = ace->next;
1866             }
1867         }
1868     }
1869
1870     // Find the next ACL corresponding to the 'subjectID' and return it.
1871     LL_FOREACH(begin, ace)
1872     {
1873         if (memcmp(&(ace->subjectuuid), subjectId, sizeof(OicUuid_t)) == 0)
1874         {
1875             *savePtr = ace;
1876             return ace;
1877         }
1878     }
1879
1880     // Cleanup in case no ACL is found
1881     *savePtr = NULL;
1882     return NULL;
1883 }
1884
1885 OCStackResult InstallNewACL(const uint8_t *cborPayload, const size_t size)
1886 {
1887     OCStackResult ret = OC_STACK_ERROR;
1888
1889     // Convert CBOR format to ACL data. This will also validate the ACL data received.
1890     OicSecAcl_t* newAcl = CBORPayloadToAcl(cborPayload, size);
1891
1892     if (newAcl)
1893     {
1894         // Append the new ACL to existing ACL
1895         OicSecAce_t* newAce = NULL;
1896         LL_FOREACH(newAcl->aces, newAce)
1897         {
1898             LL_APPEND(gAcl->aces, newAce);
1899         }
1900
1901         size_t size = 0;
1902         uint8_t *payload = NULL;
1903         if (OC_STACK_OK == AclToCBORPayload(gAcl, &payload, &size))
1904         {
1905             if (UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, payload, size) == OC_STACK_OK)
1906             {
1907                 ret = OC_STACK_OK;
1908             }
1909             OICFree(payload);
1910         }
1911     }
1912
1913     return ret;
1914 }
1915
1916 /**
1917  * This function generates default ACE for security resource in case of owned status.
1918  *
1919  * @return Default ACE for security resource.
1920  */
1921 static OicSecAce_t* GetSecDefaultACE()
1922 {
1923     const int NUM_OF_DOXM_RT = 1;
1924     const int NUM_OF_DOXM_IF  = 1;
1925     const int NUM_OF_PSTAT_RT = 1;
1926     const int NUM_OF_PSTAT_IF = 1;
1927     const char *doxmRt[] = { OIC_RSRC_TYPE_SEC_DOXM };
1928     const char *pstatRt[] = { OIC_RSRC_TYPE_SEC_PSTAT };
1929     const char *doxmIf[] = { OC_RSRVD_INTERFACE_DEFAULT };
1930     const char *pstatIf[] = { OC_RSRVD_INTERFACE_DEFAULT };
1931     OicSecRsrc_t* doxmRsrc = NULL;
1932     OicSecRsrc_t* pstatRsrc = NULL;
1933
1934     //Generate default ACE
1935     OicSecAce_t* newAce = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
1936     VERIFY_NON_NULL(TAG, newAce, ERROR);
1937
1938     // Subject -- Mandatory
1939     memcpy(newAce->subjectuuid.id, &WILDCARD_SUBJECT_ID, WILDCARD_SUBJECT_ID_LEN);
1940
1941     //Resources -- Mandatory
1942     //Add doxm
1943     doxmRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1944     VERIFY_NON_NULL(TAG, doxmRsrc, ERROR);
1945     LL_APPEND(newAce->resources, doxmRsrc);
1946     // pstat-href
1947     doxmRsrc->href = OICStrdup(OIC_RSRC_DOXM_URI);
1948     VERIFY_NON_NULL(TAG, (doxmRsrc->href), ERROR);
1949     // pstat-rt
1950     doxmRsrc->typeLen = NUM_OF_DOXM_RT;
1951     doxmRsrc->types = (char**)OICCalloc(NUM_OF_DOXM_RT, sizeof(char*));
1952     VERIFY_NON_NULL(TAG, (doxmRsrc->types), ERROR);
1953     for(int i = 0; i < NUM_OF_DOXM_RT; i++)
1954     {
1955         doxmRsrc->types[i] = OICStrdup(doxmRt[i]);
1956         VERIFY_NON_NULL(TAG, (doxmRsrc->types[i]), ERROR);
1957     }
1958     // pstat-if
1959     doxmRsrc->interfaceLen = NUM_OF_DOXM_IF;
1960     doxmRsrc->interfaces = (char**)OICCalloc(NUM_OF_DOXM_IF, sizeof(char*));
1961     VERIFY_NON_NULL(TAG, (doxmRsrc->interfaces), ERROR);
1962     for(int i = 0; i < NUM_OF_DOXM_IF; i++)
1963     {
1964         doxmRsrc->interfaces[i] = OICStrdup(doxmIf[i]);
1965         VERIFY_NON_NULL(TAG, (doxmRsrc->interfaces[i]), ERROR);
1966     }
1967
1968     //Add pstat
1969     pstatRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1970     VERIFY_NON_NULL(TAG, pstatRsrc, ERROR);
1971     LL_APPEND(newAce->resources, pstatRsrc);
1972     //pstat-href
1973     pstatRsrc->href = OICStrdup(OIC_RSRC_PSTAT_URI);
1974     VERIFY_NON_NULL(TAG, (pstatRsrc->href), ERROR);
1975     //pstat-rt
1976     pstatRsrc->typeLen = NUM_OF_PSTAT_RT;
1977     pstatRsrc->types = (char**)OICCalloc(NUM_OF_PSTAT_RT, sizeof(char*));
1978     VERIFY_NON_NULL(TAG, (pstatRsrc->types), ERROR);
1979     for(int i = 0; i < NUM_OF_PSTAT_RT; i++)
1980     {
1981         pstatRsrc->types[i] = OICStrdup(pstatRt[i]);
1982         VERIFY_NON_NULL(TAG, (pstatRsrc->types[i]), ERROR);
1983     }
1984     // pstat-if
1985     pstatRsrc->interfaceLen = NUM_OF_PSTAT_IF;
1986     pstatRsrc->interfaces = (char**)OICCalloc(NUM_OF_PSTAT_IF, sizeof(char*));
1987     VERIFY_NON_NULL(TAG, (pstatRsrc->interfaces), ERROR);
1988     for(int i = 0; i < NUM_OF_PSTAT_IF; i++)
1989     {
1990         pstatRsrc->interfaces[i] = OICStrdup(pstatIf[i]);
1991         VERIFY_NON_NULL(TAG, (pstatRsrc->interfaces[i]), ERROR);
1992     }
1993
1994     // Permissions -- Mandatory
1995     newAce->permission = PERMISSION_READ;
1996
1997     //Period -- Not Mandatory
1998     newAce->validities = NULL;
1999
2000     return newAce;
2001 exit:
2002     FreeACE(newAce);
2003     return NULL;
2004
2005 }
2006
2007 OCStackResult UpdateDefaultSecProvACE()
2008 {
2009     OCStackResult ret = OC_STACK_OK;
2010     OicSecAce_t *ace = NULL;
2011     OicSecAce_t *tempAce = NULL;
2012
2013     if(gAcl)
2014     {
2015         int matchedRsrc = 0;
2016         bool isRemoved = false;
2017
2018         LL_FOREACH_SAFE(gAcl->aces, ace, tempAce)
2019         {
2020             //Find default security resource ACL
2021             if(memcmp(&ace->subjectuuid, &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t)) == 0 &&
2022                 ((PERMISSION_READ | PERMISSION_WRITE) == ace->permission))
2023             {
2024                 matchedRsrc = 0;
2025
2026                 OicSecRsrc_t* rsrc = NULL;
2027                 LL_FOREACH(ace->resources, rsrc)
2028                 {
2029                     if(strncmp(rsrc->href, OIC_RSRC_DOXM_URI,
2030                                strlen(OIC_RSRC_DOXM_URI) + 1) == 0 ||
2031                        strncmp(rsrc->href, OIC_RSRC_CRED_URI,
2032                                strlen(OIC_RSRC_CRED_URI) + 1) == 0 ||
2033                        strncmp(rsrc->href, OIC_RSRC_ACL_URI,
2034                                strlen(OIC_RSRC_ACL_URI) + 1) == 0 ||
2035                        strncmp(rsrc->href, OIC_RSRC_PSTAT_URI,
2036                                strlen(OIC_RSRC_PSTAT_URI) + 1) == 0)
2037                     {
2038                         matchedRsrc++;
2039                     }
2040                 }
2041
2042                 //If default security resource ACL is detected, delete it.
2043                 if(NUMBER_OF_SEC_PROV_RSCS == matchedRsrc)
2044                 {
2045                     LL_DELETE(gAcl->aces, ace);
2046                     FreeACE(ace);
2047                     isRemoved = true;
2048                 }
2049             }
2050         }
2051
2052         if(isRemoved)
2053         {
2054             /*
2055              * Generate new security resource ACE as follows :
2056              *      subject : "*"
2057              *      resources :  '/oic/sec/doxm', '/oic/sec/pstat'
2058              *      permission : READ
2059              */
2060             OicSecAce_t *secDefaultAce = GetSecDefaultACE();
2061             if (secDefaultAce)
2062             {
2063                 LL_APPEND(gAcl->aces, secDefaultAce);
2064
2065                 size_t size = 0;
2066                 uint8_t *payload = NULL;
2067                 if (OC_STACK_OK == AclToCBORPayload(gAcl, &payload, &size))
2068                 {
2069                     if (UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, payload, size) == OC_STACK_OK)
2070                     {
2071                         ret = OC_STACK_OK;
2072                     }
2073                     OICFree(payload);
2074                 }
2075             }
2076         }
2077     }
2078
2079     return ret;
2080 }
2081
2082 OCStackResult SetAclRownerId(const OicUuid_t* newROwner)
2083 {
2084     OCStackResult ret = OC_STACK_ERROR;
2085     uint8_t *cborPayload = NULL;
2086     size_t size = 0;
2087     OicUuid_t prevId = {.id={0}};
2088
2089     if(NULL == newROwner)
2090     {
2091         ret = OC_STACK_INVALID_PARAM;
2092     }
2093     if(NULL == gAcl)
2094     {
2095         ret = OC_STACK_NO_RESOURCE;
2096     }
2097
2098     if(newROwner && gAcl)
2099     {
2100         memcpy(prevId.id, gAcl->rownerID.id, sizeof(prevId.id));
2101         memcpy(gAcl->rownerID.id, newROwner->id, sizeof(newROwner->id));
2102
2103         ret = AclToCBORPayload(gAcl, &cborPayload, &size);
2104         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2105
2106         ret = UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, cborPayload, size);
2107         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2108
2109         OICFree(cborPayload);
2110     }
2111
2112     return ret;
2113
2114 exit:
2115     OICFree(cborPayload);
2116     memcpy(gAcl->rownerID.id, prevId.id, sizeof(prevId.id));
2117     return ret;
2118 }
2119
2120 OCStackResult GetAclRownerId(OicUuid_t *rowneruuid)
2121 {
2122     OCStackResult retVal = OC_STACK_ERROR;
2123     if (gAcl)
2124     {
2125         *rowneruuid = gAcl->rownerID;
2126         retVal = OC_STACK_OK;
2127     }
2128     return retVal;
2129 }