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