e3aef30cf4c740ee9b9a1fec6cae36d8575f9b16
[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 HAVE_STRING_H
22 #include <string.h>
23 #elif HAVE_STRINGS_H
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 = 2;
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 = 4;
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                 cborEncoderResult = cbor_encoder_create_map(&resources, &rMap, ACL_RESOURCE_MAP_SIZE);
400                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Resource Map.");
401
402                 //href -- Mandatory
403                 VERIFY_NON_NULL(TAG, rsrc->href, ERROR);
404                 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_HREF_NAME,
405                         strlen(OIC_JSON_HREF_NAME));
406                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding HREF Name Tag.");
407                 cborEncoderResult = cbor_encode_text_string(&rMap, rsrc->href, strlen(rsrc->href));
408                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding HREF Value in Map.");
409
410                 //resource type -- Mandatory
411                 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_RT_NAME,
412                         strlen(OIC_JSON_RT_NAME));
413                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
414
415                 CborEncoder resourceTypes;
416                 cborEncoderResult = cbor_encoder_create_array(&rMap, &resourceTypes, rsrc->typeLen);
417                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding RT Array.");
418                 for(size_t i = 0; i < rsrc->typeLen; i++)
419                 {
420                     cborEncoderResult = cbor_encode_text_string(&resourceTypes, rsrc->types[i], strlen(rsrc->types[i]));
421                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Value.");
422                 }
423                 cborEncoderResult = cbor_encoder_close_container(&rMap, &resourceTypes);
424                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing resourceTypes.");
425
426                 //interface -- Mandatory
427                 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_IF_NAME,
428                         strlen(OIC_JSON_IF_NAME));
429                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
430
431                 CborEncoder interfaces;
432                 cborEncoderResult = cbor_encoder_create_array(&rMap, &interfaces, rsrc->interfaceLen);
433                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding IF Array.");
434                 for(size_t i = 0; i < rsrc->interfaceLen; i++)
435                 {
436                     cborEncoderResult = cbor_encode_text_string(&interfaces, rsrc->interfaces[i], strlen(rsrc->interfaces[i]));
437                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
438                 }
439                 cborEncoderResult = cbor_encoder_close_container(&rMap, &interfaces);
440                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing interfaces.");
441
442                 //rel
443                 if(rsrc->rel)
444                 {
445                     cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_REL_NAME,
446                             strlen(OIC_JSON_REL_NAME));
447                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding REL Name Tag.");
448                     cborEncoderResult = cbor_encode_text_string(&rMap, rsrc->rel, strlen(rsrc->rel));
449                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding REL Value.");
450                 }
451                 else
452                 {
453                     cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_REL_NAME,
454                             strlen(OIC_JSON_REL_NAME));
455                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding REL Name Tag.");
456                     cborEncoderResult = cbor_encode_text_string(&rMap, "", 0);
457                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding REL Value.");
458                 }
459
460                 cborEncoderResult = cbor_encoder_close_container(&resources, &rMap);
461                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Resource Map.");
462             }
463             cborEncoderResult = cbor_encoder_close_container(&oicSecAclMap, &resources);
464             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Resource Name Array.");
465         }
466
467         // Permissions -- Mandatory
468         cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, OIC_JSON_PERMISSION_NAME,
469             strlen(OIC_JSON_PERMISSION_NAME));
470         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Permission Name Tag.");
471         cborEncoderResult = cbor_encode_int(&oicSecAclMap, ace->permission);
472         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Permission Name Value.");
473
474         // TODO: Need to verfication for validity
475         // Validity(Time-interval) -- Not Mandatory
476         if(ace->validities)
477         {
478             size_t validityLen = 0;
479             validityElts = NULL;
480             LL_FOREACH(ace->validities, validityElts)
481             {
482                 validityLen++;
483             }
484
485             CborEncoder validities;
486             cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, OIC_JSON_VALIDITY_NAME,
487                 strlen(OIC_JSON_VALIDITY_NAME));
488             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Validity Tag.");
489             cborEncoderResult = cbor_encoder_create_array(&oicSecAclMap, &validities, validityLen);
490             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Validities Array.");
491
492             //How to add the value w/o "title" using tinycobr...? :(
493
494             validityElts = NULL;
495             LL_FOREACH(ace->validities, validityElts)
496             {
497                  CborEncoder validity;
498                  size_t validitySize = 0;
499                  if(validityElts->period)
500                 {
501                     validitySize++;
502                 }
503                 if(validityElts->recurrences)
504                 {
505                     validitySize++;
506                 }
507
508                 cborEncoderResult = cbor_encoder_create_array(&validities, &validity, validitySize);
509                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Validity Array.");
510
511                 // Period
512                 if (validityElts->period)
513                 {
514                     cborEncoderResult = cbor_encode_text_string(&validity, validityElts->period,
515                         strlen(validityElts->period));
516                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Value.");
517                 }
518
519                 // Recurrence
520                 if (validityElts->recurrences)
521                 {
522                     CborEncoder recurrences;
523                     cborEncoderResult = cbor_encoder_create_array(&validity, &recurrences, validityElts->recurrenceLen);
524                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Recurrence Array.");
525
526                     for (size_t i = 0; i < validityElts->recurrenceLen; i++)
527                     {
528                         cborEncoderResult = cbor_encode_text_string(&recurrences, validityElts->recurrences[i],
529                             strlen(validityElts->recurrences[i]));
530                         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Recurrence Array Value.");
531                     }
532                     cborEncoderResult = cbor_encoder_close_container(&validity, &recurrences);
533                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Recurrence Array");
534                 }
535
536                 cborEncoderResult = cbor_encoder_close_container(&validities, &validity);
537                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Validity Array.");
538             }
539
540             cborEncoderResult = cbor_encoder_close_container(&oicSecAclMap, &validities);
541             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Validities Array.");
542         }
543
544         cborEncoderResult = cbor_encoder_close_container(&acesArray, &oicSecAclMap);
545         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing ACES Map.");
546     }
547
548     // Close ACES Array
549     cborEncoderResult = cbor_encoder_close_container(&aclListMap, &acesArray);
550     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing ACES Array.");
551
552     // Close ACLIST Map
553     cborEncoderResult = cbor_encoder_close_container(&aclMap, &aclListMap);
554     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing ACLIST Map.");
555
556     // Rownerid
557     {
558         char *rowner = NULL;
559         cborEncoderResult = cbor_encode_text_string(&aclMap, OIC_JSON_ROWNERID_NAME,
560             strlen(OIC_JSON_ROWNERID_NAME));
561         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding rownerid Name.");
562         ret = ConvertUuidToStr(&secAcl->rownerID, &rowner);
563         VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
564         cborEncoderResult = cbor_encode_text_string(&aclMap, rowner, strlen(rowner));
565         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding rownerid Value.");
566         OICFree(rowner);
567     }
568
569     // Close ACL Map
570     cborEncoderResult = cbor_encoder_close_container(&encoder, &aclMap);
571     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing ACL Map.");
572
573     if (CborNoError == cborEncoderResult)
574     {
575         OIC_LOG(DEBUG, TAG, "AclToCBORPayload Successed");
576         *size = encoder.ptr - outPayload;
577         *payload = outPayload;
578         ret = OC_STACK_OK;
579     }
580 exit:
581     if (CborErrorOutOfMemory == cborEncoderResult)
582     {
583         OIC_LOG(DEBUG, TAG, "AclToCBORPayload:CborErrorOutOfMemory : retry with more memory");
584
585         // reallocate and try again!
586         OICFree(outPayload);
587         // Since the allocated initial memory failed, double the memory.
588         cborLen += encoder.ptr - encoder.end;
589         cborEncoderResult = CborNoError;
590         ret = AclToCBORPayload(secAcl, payload, &cborLen);
591         *size = cborLen;
592     }
593     else if (cborEncoderResult != CborNoError)
594     {
595         OIC_LOG(ERROR, TAG, "Failed to AclToCBORPayload");
596         OICFree(outPayload);
597         outPayload = NULL;
598         *size = 0;
599         *payload = NULL;
600         ret = OC_STACK_ERROR;
601     }
602
603     return ret;
604 }
605
606 // This function converts CBOR format to ACL data.
607 // Caller needs to invoke 'free' when done using
608 // note: This function is used in unit test hence not declared static,
609 OicSecAcl_t* CBORPayloadToAcl(const uint8_t *cborPayload, const size_t size)
610 {
611     if (NULL == cborPayload || 0 == size)
612     {
613         return NULL;
614     }
615     OCStackResult ret = OC_STACK_ERROR;
616     CborValue aclCbor = { .parser = NULL };
617     CborParser parser = { .end = NULL };
618     CborError cborFindResult = CborNoError;
619     cbor_parser_init(cborPayload, size, 0, &parser, &aclCbor);
620
621     OicSecAcl_t *acl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
622
623     // Enter ACL Map
624     CborValue aclMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
625     cborFindResult = cbor_value_enter_container(&aclCbor, &aclMap);
626     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACL Map.");
627
628     while (cbor_value_is_valid(&aclMap))
629     {
630         char* tagName = NULL;
631         size_t len = 0;
632         CborType type = cbor_value_get_type(&aclMap);
633         if (type == CborTextStringType)
634         {
635             cborFindResult = cbor_value_dup_text_string(&aclMap, &tagName, &len, NULL);
636             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in ACL Map.");
637             cborFindResult = cbor_value_advance(&aclMap);
638             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in ACL Map.");
639         }
640         if(tagName)
641         {
642             if (strcmp(tagName, OIC_JSON_ACLIST_NAME)  == 0)
643             {
644                 // Enter ACLIST Map
645                 CborValue aclistMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
646                 cborFindResult = cbor_value_enter_container(&aclMap, &aclistMap);
647                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACLIST Map.");
648
649
650                 while (cbor_value_is_valid(&aclistMap))
651                 {
652                     char* acName = NULL;
653                     size_t readLen = 0;
654                     CborType acType = cbor_value_get_type(&aclistMap);
655                     if (acType == CborTextStringType)
656                     {
657                         cborFindResult = cbor_value_dup_text_string(&aclistMap, &acName, &readLen, NULL);
658                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in ACLIST Map.");
659                         cborFindResult = cbor_value_advance(&aclistMap);
660                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in ACLIST Map.");
661                     }
662
663                     if(acName)
664                     {
665                         if (strcmp(acName, OIC_JSON_ACES_NAME)  == 0)
666                         {
667                             // Enter ACES Array
668                             CborValue acesArray = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
669                             cborFindResult = cbor_value_enter_container(&aclistMap, &acesArray);
670                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACES Array.");
671
672                             int acesCount = 0;
673                             while (cbor_value_is_valid(&acesArray))
674                             {
675                                 acesCount++;
676                                 CborValue aceMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
677                                 cborFindResult = cbor_value_enter_container(&acesArray, &aceMap);
678                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACE Map.");
679
680                                 OicSecAce_t *ace = NULL;
681                                 ace = (OicSecAce_t *) OICCalloc(1, sizeof(OicSecAce_t));
682                                 VERIFY_NON_NULL(TAG, ace, ERROR);
683                                 LL_APPEND(acl->aces, ace);
684
685                                 VERIFY_NON_NULL(TAG, acl, ERROR);
686
687                                 while (cbor_value_is_valid(&aceMap))
688                                 {
689                                     char* name = NULL;
690                                     size_t len = 0;
691                                     CborType type = cbor_value_get_type(&aceMap);
692                                     if (type == CborTextStringType)
693                                     {
694                                         cborFindResult = cbor_value_dup_text_string(&aceMap, &name, &len, NULL);
695                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in ACE Map.");
696                                         cborFindResult = cbor_value_advance(&aceMap);
697                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in ACE Map.");
698                                     }
699                                     if (name)
700                                     {
701                                         // Subject -- Mandatory
702                                         if (strcmp(name, OIC_JSON_SUBJECTID_NAME)  == 0)
703                                         {
704                                             char *subject = NULL;
705                                             cborFindResult = cbor_value_dup_text_string(&aceMap, &subject, &len, NULL);
706                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding subject Value.");
707                                             if(strcmp(subject, WILDCARD_RESOURCE_URI) == 0)
708                                             {
709                                                 ace->subjectuuid.id[0] = '*';
710                                             }
711                                             else
712                                             {
713                                                 ret = ConvertStrToUuid(subject, &ace->subjectuuid);
714                                                 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
715                                             }
716                                             OICFree(subject);
717                                         }
718
719                                         // Resources -- Mandatory
720                                         if (strcmp(name, OIC_JSON_RESOURCES_NAME) == 0)
721                                         {
722                                             CborValue resources = { .parser = NULL };
723                                             cborFindResult = cbor_value_enter_container(&aceMap, &resources);
724                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering a Resource Array.");
725
726                                             while (cbor_value_is_valid(&resources))
727                                             {
728                                                 // rMap
729                                                 CborValue rMap = { .parser = NULL  };
730                                                 cborFindResult = cbor_value_enter_container(&resources, &rMap);
731                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering Resource Map");
732
733                                                 OicSecRsrc_t* rsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
734                                                 VERIFY_NON_NULL(TAG, rsrc, ERROR);
735                                                 LL_APPEND(ace->resources, rsrc);
736
737                                                 while(cbor_value_is_valid(&rMap))
738                                                 {
739                                                     char *rMapName = NULL;
740                                                     size_t rMapNameLen = 0;
741                                                     cborFindResult = cbor_value_dup_text_string(&rMap, &rMapName, &rMapNameLen, NULL);
742                                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Name Tag.");
743                                                     cborFindResult = cbor_value_advance(&rMap);
744                                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Value.");
745
746                                                     // "href"
747                                                     if (0 == strcmp(OIC_JSON_HREF_NAME, rMapName))
748                                                     {
749                                                         cborFindResult = cbor_value_dup_text_string(&rMap, &rsrc->href, &len, NULL);
750                                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Href Value.");
751                                                     }
752
753                                                     // "rt"
754                                                     if (0 == strcmp(OIC_JSON_RT_NAME, rMapName) && cbor_value_is_array(&rMap))
755                                                     {
756                                                         cbor_value_get_array_length(&rMap, &rsrc->typeLen);
757                                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RT array length.");
758                                                         VERIFY_SUCCESS(TAG, (0 != rsrc->typeLen), ERROR);
759
760                                                         rsrc->types = (char**)OICCalloc(rsrc->typeLen, sizeof(char*));
761                                                         VERIFY_NON_NULL(TAG, rsrc->types, ERROR);
762
763                                                         CborValue resourceTypes;
764                                                         cborFindResult = cbor_value_enter_container(&rMap, &resourceTypes);
765                                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering RT Array.");
766
767                                                         for(size_t i = 0; cbor_value_is_valid(&resourceTypes) && cbor_value_is_text_string(&resourceTypes); i++)
768                                                         {
769                                                             cborFindResult = cbor_value_dup_text_string(&resourceTypes, &(rsrc->types[i]), &readLen, NULL);
770                                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding resource type.");
771                                                             cborFindResult = cbor_value_advance(&resourceTypes);
772                                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing resource type.");
773                                                         }
774                                                     }
775
776                                                     // "if"
777                                                     if (0 == strcmp(OIC_JSON_IF_NAME, rMapName) && cbor_value_is_array(&rMap))
778                                                     {
779                                                         cbor_value_get_array_length(&rMap, &rsrc->interfaceLen);
780                                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding IF array length.");
781                                                         VERIFY_SUCCESS(TAG, (0 != rsrc->interfaceLen), ERROR);
782
783                                                         rsrc->interfaces = (char**)OICCalloc(rsrc->interfaceLen, sizeof(char*));
784                                                         VERIFY_NON_NULL(TAG, rsrc->interfaces, ERROR);
785
786                                                         CborValue interfaces;
787                                                         cborFindResult = cbor_value_enter_container(&rMap, &interfaces);
788                                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering IF Array.");
789
790                                                         for(size_t i = 0; cbor_value_is_valid(&interfaces) && cbor_value_is_text_string(&interfaces); i++)
791                                                         {
792                                                             cborFindResult = cbor_value_dup_text_string(&interfaces, &(rsrc->interfaces[i]), &readLen, NULL);
793                                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding IF type.");
794                                                             cborFindResult = cbor_value_advance(&interfaces);
795                                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing IF type.");
796                                                         }
797                                                     }
798
799                                                     // "rel"
800                                                     if (0 == strcmp(OIC_JSON_REL_NAME, rMapName))
801                                                     {
802                                                         cborFindResult = cbor_value_dup_text_string(&rMap, &rsrc->rel, &len, NULL);
803                                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding REL Value.");
804                                                     }
805
806                                                     if (cbor_value_is_valid(&rMap))
807                                                     {
808                                                         cborFindResult = cbor_value_advance(&rMap);
809                                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Rlist Map.");
810                                                     }
811                                                     OICFree(rMapName);
812                                                 }
813
814                                                 if (cbor_value_is_valid(&resources))
815                                                 {
816                                                     cborFindResult = cbor_value_advance(&resources);
817                                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Resource Array.");
818                                                 }
819                                             }
820                                         }
821
822                                         // Permissions -- Mandatory
823                                         if (strcmp(name, OIC_JSON_PERMISSION_NAME) == 0)
824                                         {
825                                             uint64_t tmp64;
826                                             cborFindResult = cbor_value_get_uint64(&aceMap, &tmp64);
827                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a PERM Value.");
828                                             ace->permission = (uint16_t)tmp64;
829                                         }
830
831                                         // TODO: Need to verfication for validity
832                                         // Validity -- Not mandatory
833                                         if(strcmp(name, OIC_JSON_VALIDITY_NAME) == 0)
834                                         {
835                                             CborValue validitiesMap = {.parser = NULL};
836                                             size_t validitySize = 0;
837
838                                             cborFindResult = cbor_value_get_array_length(&aceMap, &validitySize);
839                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a Validity Array Length.");
840
841                                             cborFindResult = cbor_value_enter_container(&aceMap, &validitiesMap);
842                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a validity Array Map.");
843
844                                             while(cbor_value_is_valid(&validitiesMap))
845                                             {
846                                                 OicSecValidity_t* validity = (OicSecValidity_t*)OICCalloc(1, sizeof(OicSecValidity_t));
847                                                 VERIFY_NON_NULL(TAG, validity, ERROR);
848                                                 LL_APPEND(ace->validities, validity);
849
850                                                 CborValue validityMap  = {.parser = NULL};
851                                                 //period (string)
852                                                 cborFindResult = cbor_value_enter_container(&validitiesMap, &validityMap);
853                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a validity Map.");
854
855                                                 size_t len = 0;
856                                                 cborFindResult =cbor_value_dup_text_string(&validityMap, &validity->period, &len, NULL);
857                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a Period value.");
858
859                                                 //recurrence (string array)
860                                                 CborValue recurrenceMap  = {.parser = NULL};
861                                                 cborFindResult = cbor_value_enter_container(&validityMap, &recurrenceMap);
862                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a recurrence array.");
863
864                                                 cborFindResult = cbor_value_get_array_length(&recurrenceMap, &validity->recurrenceLen);
865                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Adding Recurrence Array.");
866
867                                                 validity->recurrences = (char**)OICCalloc(validity->recurrenceLen, sizeof(char*));
868                                                 VERIFY_NON_NULL(TAG, validity->recurrences, ERROR);
869
870                                                 for(size_t i = 0; cbor_value_is_text_string(&recurrenceMap) && i < validity->recurrenceLen; i++)
871                                                 {
872                                                     cborFindResult = cbor_value_dup_text_string(&recurrenceMap, &validity->recurrences[i], &len, NULL);
873                                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a recurrence Value.");
874
875                                                     cborFindResult = cbor_value_advance(&recurrenceMap);
876                                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing a recurrences Array.");
877                                                 }
878
879                                                 cborFindResult = cbor_value_advance(&validitiesMap);
880                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing a validities Array.");
881                                             }
882                                         }
883                                         OICFree(name);
884                                     }
885
886                                     if (type != CborMapType && cbor_value_is_valid(&aceMap))
887                                     {
888                                         cborFindResult = cbor_value_advance(&aceMap);
889                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing the Array.");
890                                     }
891                                 }
892
893                                 if (cbor_value_is_valid(&acesArray))
894                                 {
895                                     cborFindResult = cbor_value_advance(&acesArray);
896                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing ACL Array.");
897                                 }
898                             }
899                         }
900                         OICFree(acName);
901                     }
902
903                     if (cbor_value_is_valid(&aclistMap))
904                     {
905                         cborFindResult = cbor_value_advance(&aclistMap);
906                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing ACLIST Map.");
907                     }
908                 }
909             }
910
911             //rownerID -- Mandatory
912             if (strcmp(tagName, OIC_JSON_ROWNERID_NAME)  == 0)
913             {
914                 char *stRowner = NULL;
915                 cborFindResult = cbor_value_dup_text_string(&aclMap, &stRowner, &len, NULL);
916                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Rownerid Value.");
917                 ret = ConvertStrToUuid(stRowner, &acl->rownerID);
918                 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
919                 OICFree(stRowner);
920             }
921             OICFree(tagName);
922         }
923         if (cbor_value_is_valid(&aclMap))
924         {
925             cborFindResult = cbor_value_advance(&aclMap);
926             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing ACL Map.");
927         }
928     }
929
930 exit:
931     if (cborFindResult != CborNoError)
932     {
933         OIC_LOG(ERROR, TAG, "Failed to CBORPayloadToAcl");
934         DeleteACLList(acl);
935         acl = NULL;
936     }
937
938     return acl;
939 }
940
941 /**
942  * This method removes ACE for the subject and resource from the ACL
943  *
944  * @param subject of the ACE
945  * @param resource of the ACE
946  *
947  * @return
948  *     ::OC_STACK_RESOURCE_DELETED on success
949  *     ::OC_STACK_NO_RESOURCE on failure to find the appropriate ACE
950  *     ::OC_STACK_INVALID_PARAM on invalid parameter
951  */
952 OCStackResult RemoveACE(const OicUuid_t * subject, const char * resource)
953 {
954     OIC_LOG(DEBUG, TAG, "IN RemoveACE");
955
956     OicSecAce_t *ace = NULL;
957     OicSecAce_t *tempAce = NULL;
958     bool deleteFlag = false;
959     OCStackResult ret = OC_STACK_NO_RESOURCE;
960
961     if (memcmp(subject->id, &WILDCARD_SUBJECT_ID, sizeof(subject->id)) == 0)
962     {
963         OIC_LOG_V(ERROR, TAG, "%s received invalid parameter", __func__ );
964         return  OC_STACK_INVALID_PARAM;
965     }
966
967     //If resource is NULL then delete all the ACE for the subject.
968     if (NULL == resource || resource[0] == '\0')
969     {
970         LL_FOREACH_SAFE(gAcl->aces, ace, tempAce)
971         {
972             if (memcmp(ace->subjectuuid.id, subject->id, sizeof(subject->id)) == 0)
973             {
974                 LL_DELETE(gAcl->aces, ace);
975                 FreeACE(ace);
976                 deleteFlag = true;
977             }
978         }
979     }
980     else
981     {
982         //Looping through ACL to find the right ACE to delete. If the required resource is the only
983         //resource in the ACE for the subject then delete the whole ACE. If there are more resources
984         //than the required resource in the ACE, for the subject then just delete the resource from
985         //the resource array
986         LL_FOREACH_SAFE(gAcl->aces, ace, tempAce)
987         {
988             if (memcmp(ace->subjectuuid.id, subject->id, sizeof(subject->id)) == 0)
989             {
990                 OicSecRsrc_t* rsrc = NULL;
991                 OicSecRsrc_t* tempRsrc = NULL;
992                 LL_FOREACH_SAFE(ace->resources, rsrc, tempRsrc)
993                 {
994                     if(strcmp(rsrc->href, resource) == 0)
995                     {
996                         LL_DELETE(ace->resources, rsrc);
997                         FreeRsrc(rsrc);
998                         deleteFlag = true;
999                     }
1000                 }
1001
1002                 //If resource list is empty
1003                 if(NULL == ace->resources && true == deleteFlag)
1004                 {
1005                     //Remove the ACE from ACL
1006                     LL_DELETE(gAcl->aces, ace);
1007                     FreeACE(ace);
1008                 }
1009             }
1010         }
1011     }
1012
1013     if (deleteFlag)
1014     {
1015         // In case of unit test do not update persistant storage.
1016         if (memcmp(subject->id, &WILDCARD_SUBJECT_B64_ID, sizeof(subject->id)) == 0)
1017         {
1018             ret = OC_STACK_RESOURCE_DELETED;
1019         }
1020         else
1021         {
1022             uint8_t *payload = NULL;
1023             size_t size = 0;
1024             if (OC_STACK_OK == AclToCBORPayload(gAcl, &payload, &size))
1025             {
1026                 if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, payload, size))
1027                 {
1028                     ret = OC_STACK_RESOURCE_DELETED;
1029                 }
1030                 OICFree(payload);
1031             }
1032         }
1033     }
1034     return ret;
1035 }
1036
1037 /**
1038  * This method parses the query string received for REST requests and
1039  * retrieves the 'subject' field.
1040  *
1041  * @param query querystring passed in REST request
1042  * @param subject subject UUID parsed from query string
1043  *
1044  * @return true if query parsed successfully and found 'subject', else false.
1045  */
1046 static bool GetSubjectFromQueryString(const char *query, OicUuid_t *subject)
1047 {
1048     OicParseQueryIter_t parseIter = { .attrPos = NULL };
1049
1050     ParseQueryIterInit((unsigned char *) query, &parseIter);
1051
1052     while (GetNextQuery (&parseIter))
1053     {
1054         if (strncasecmp((char *) parseIter.attrPos, OIC_JSON_SUBJECTID_NAME, parseIter.attrLen) == 0)
1055         {
1056             char strUuid[STRING_UUID_SIZE] = {0};
1057             VERIFY_SUCCESS(TAG, 0 != parseIter.valLen, ERROR);
1058             memcpy(strUuid, parseIter.valPos, parseIter.valLen);
1059             OCStackResult res = ConvertStrToUuid(strUuid, subject);
1060             VERIFY_SUCCESS(TAG, OC_STACK_OK == res, ERROR);
1061             return true;
1062         }
1063     }
1064
1065 exit:
1066     return false;
1067 }
1068
1069 /**
1070  * This method parses the query string received for REST requests and
1071  * retrieves the 'resource' field.
1072  *
1073  * @param query querystring passed in REST request
1074  * @param resource resource parsed from query string
1075  * @param resourceSize size of the memory pointed to resource
1076  *
1077  * @return true if query parsed successfully and found 'resource', else false.
1078  */
1079 static bool GetResourceFromQueryString(const char *query, char *resource, size_t resourceSize)
1080 {
1081     OicParseQueryIter_t parseIter = { .attrPos = NULL };
1082
1083     ParseQueryIterInit((unsigned char *) query, &parseIter);
1084
1085     while (GetNextQuery (&parseIter))
1086     {
1087         if (strncasecmp((char *) parseIter.attrPos, OIC_JSON_RESOURCES_NAME, parseIter.attrLen)
1088                 == 0)
1089         {
1090             VERIFY_SUCCESS(TAG, 0 != parseIter.valLen, ERROR);
1091             OICStrcpy(resource, resourceSize, (char *) parseIter.valPos);
1092
1093             return true;
1094         }
1095     }
1096
1097 exit:
1098    return false;
1099 }
1100
1101 static OCEntityHandlerResult HandleACLGetRequest(const OCEntityHandlerRequest *ehRequest)
1102 {
1103     OIC_LOG(INFO, TAG, "HandleACLGetRequest processing the request");
1104     uint8_t* payload = NULL;
1105     size_t size = 0;
1106     OCEntityHandlerResult ehRet;
1107
1108     OicUuid_t subject = {.id= { 0 } };
1109
1110     // In case, 'subject' field is included in REST request.
1111     if (ehRequest->query && GetSubjectFromQueryString(ehRequest->query, &subject))
1112     {
1113         OIC_LOG(DEBUG,TAG,"'subject' field is inculded in REST request.");
1114         OIC_LOG(DEBUG, TAG, "HandleACLGetRequest processing query");
1115
1116         char resource[MAX_URI_LENGTH] = { 0 };
1117
1118         OicSecAce_t *savePtr = NULL;
1119         const OicSecAce_t *currentAce = NULL;
1120         OicSecAcl_t targetAcl;
1121
1122         memcpy(&targetAcl.rownerID, &gAcl->rownerID, sizeof(OicUuid_t));
1123         targetAcl.aces = NULL;
1124
1125         // 'Subject' field is MUST for processing a querystring in REST request.
1126         GetResourceFromQueryString(ehRequest->query, resource, sizeof(resource));
1127
1128         /*
1129          * TODO : Currently, this code only provides one ACE for a Subject.
1130          * Below code needs to be updated for scenarios when Subject have
1131          * multiple ACE's in ACL resource.
1132          */
1133         while ((currentAce = GetACLResourceData(&subject, &savePtr)))
1134         {
1135             targetAcl.aces = (OicSecAce_t*)currentAce;
1136
1137             /*
1138              * If REST querystring contains a specific resource, we need
1139              * to search for that resource in ACE.
1140              */
1141             if (resource[0] != '\0')
1142             {
1143                 OicSecRsrc_t *rsrc = NULL;
1144                 LL_FOREACH(currentAce->resources, rsrc)
1145                 {
1146                     if(0 == strcmp(rsrc->href, resource) ||
1147                         0 == strcmp(WILDCARD_RESOURCE_URI, rsrc->href))
1148                     {
1149                         // Convert ACL data into CBOR format for transmission
1150                         if (OC_STACK_OK != AclToCBORPayload(&targetAcl, &payload, &size))
1151                         {
1152                             ehRet = OC_EH_ERROR;
1153                         }
1154                         goto exit;
1155                     }
1156                 }
1157             }
1158             else
1159             {
1160                 // Convert ACL data into CBOR format for transmission
1161                 if (OC_STACK_OK != AclToCBORPayload(&targetAcl, &payload, &size))
1162                 {
1163                     ehRet = OC_EH_ERROR;
1164                 }
1165                 goto exit;
1166             }
1167         }
1168     }
1169     // In case, 'subject' field is not included in REST request.
1170     else
1171     {
1172         OIC_LOG(DEBUG,TAG,"'subject' field is not inculded in REST request.");
1173         // Convert ACL data into CBOR format for transmission.
1174         if (OC_STACK_OK != AclToCBORPayload(gAcl, &payload, &size))
1175         {
1176             ehRet = OC_EH_ERROR;
1177         }
1178     }
1179 exit:
1180     // A device should always have a default acl. Therefore, payload should never be NULL.
1181     ehRet = (payload ? OC_EH_OK : OC_EH_ERROR);
1182
1183     // Send response payload to request originator
1184     if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, payload, size))
1185     {
1186         ehRet = OC_EH_ERROR;
1187         OIC_LOG(ERROR, TAG, "SendSRMResponse failed for HandleACLGetRequest");
1188     }
1189     OICFree(payload);
1190
1191     OIC_LOG_V(DEBUG, TAG, "%s RetVal %d", __func__, ehRet);
1192     return ehRet;
1193 }
1194
1195 static OCEntityHandlerResult HandleACLPostRequest(const OCEntityHandlerRequest *ehRequest)
1196 {
1197     OIC_LOG(INFO, TAG, "HandleACLPostRequest processing the request");
1198     OCEntityHandlerResult ehRet = OC_EH_ERROR;
1199
1200     // Convert CBOR into ACL data and update to SVR buffers. This will also validate the ACL data received.
1201     uint8_t *payload = ((OCSecurityPayload *) ehRequest->payload)->securityData;
1202     size_t size = ((OCSecurityPayload *) ehRequest->payload)->payloadSize;
1203     if (payload)
1204     {
1205         OicSecAcl_t *newAcl = CBORPayloadToAcl(payload, size);
1206         if (newAcl)
1207         {
1208             // Append the new ACL to existing ACL
1209             OicSecAce_t* newAce = NULL;
1210             OicSecAce_t* tempAce = NULL;
1211             LL_FOREACH_SAFE(newAcl->aces, newAce, tempAce)
1212             {
1213                 LL_APPEND(gAcl->aces, newAce);
1214             }
1215             newAcl->aces = NULL;
1216
1217             size_t size = 0;
1218             uint8_t *cborPayload = NULL;
1219             if (OC_STACK_OK == AclToCBORPayload(gAcl, &cborPayload, &size))
1220             {
1221                 if (UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, cborPayload, size) == OC_STACK_OK)
1222                 {
1223                     ehRet = OC_EH_RESOURCE_CREATED;
1224                 }
1225                 OICFree(cborPayload);
1226             }
1227         }
1228
1229         DeleteACLList(newAcl);
1230     }
1231
1232     // Send payload to request originator
1233     if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL, 0))
1234     {
1235         ehRet = OC_EH_ERROR;
1236         OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandleACLPostRequest");
1237     }
1238
1239     OIC_LOG_V(DEBUG, TAG, "%s RetVal %d", __func__, ehRet);
1240     return ehRet;
1241 }
1242
1243 static OCEntityHandlerResult HandleACLDeleteRequest(const OCEntityHandlerRequest *ehRequest)
1244 {
1245     OIC_LOG(DEBUG, TAG, "Processing ACLDeleteRequest");
1246     OCEntityHandlerResult ehRet = OC_EH_ERROR;
1247     OicUuid_t subject = { .id= { 0 } };
1248     char resource[MAX_URI_LENGTH] = { 0 };
1249
1250     VERIFY_NON_NULL(TAG, ehRequest->query, ERROR);
1251
1252     // 'Subject' field is MUST for processing a querystring in REST request.
1253     VERIFY_SUCCESS(TAG, true == GetSubjectFromQueryString(ehRequest->query, &subject), ERROR);
1254
1255     GetResourceFromQueryString(ehRequest->query, resource, sizeof(resource));
1256
1257     if (OC_STACK_RESOURCE_DELETED == RemoveACE(&subject, resource))
1258     {
1259         ehRet = OC_EH_RESOURCE_DELETED;
1260     }
1261
1262 exit:
1263     // Send payload to request originator
1264     if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL, 0))
1265     {
1266         ehRet = OC_EH_ERROR;
1267         OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandleACLDeleteRequest");
1268     }
1269
1270     return ehRet;
1271 }
1272
1273 OCEntityHandlerResult ACLEntityHandler(OCEntityHandlerFlag flag, OCEntityHandlerRequest * ehRequest,
1274         void* callbackParameter)
1275 {
1276     OIC_LOG(DEBUG, TAG, "Received request ACLEntityHandler");
1277     (void)callbackParameter;
1278     OCEntityHandlerResult ehRet = OC_EH_ERROR;
1279
1280     if (!ehRequest)
1281     {
1282         return ehRet;
1283     }
1284
1285     if (flag & OC_REQUEST_FLAG)
1286     {
1287         // TODO :  Handle PUT method
1288         OIC_LOG(DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
1289         switch (ehRequest->method)
1290         {
1291             case OC_REST_GET:
1292                 ehRet = HandleACLGetRequest(ehRequest);
1293                 break;
1294
1295             case OC_REST_POST:
1296                 ehRet = HandleACLPostRequest(ehRequest);
1297                 break;
1298
1299             case OC_REST_DELETE:
1300                 ehRet = HandleACLDeleteRequest(ehRequest);
1301                 break;
1302
1303             default:
1304                 ehRet = OC_EH_ERROR;
1305                 SendSRMResponse(ehRequest, ehRet, NULL, 0);
1306         }
1307     }
1308
1309     return ehRet;
1310 }
1311
1312 /**
1313  * This internal method is used to create '/oic/sec/acl' resource.
1314  */
1315 static OCStackResult CreateACLResource()
1316 {
1317     OCStackResult ret;
1318
1319     ret = OCCreateResource(&gAclHandle,
1320                            OIC_RSRC_TYPE_SEC_ACL,
1321                            OC_RSRVD_INTERFACE_DEFAULT,
1322                            OIC_RSRC_ACL_URI,
1323                            ACLEntityHandler,
1324                            NULL,
1325                            OC_OBSERVABLE | OC_SECURE | OC_EXPLICIT_DISCOVERABLE);
1326
1327     if (OC_STACK_OK != ret)
1328     {
1329         OIC_LOG(FATAL, TAG, "Unable to instantiate ACL resource");
1330         DeInitACLResource();
1331     }
1332     return ret;
1333 }
1334
1335 // This function sets the default ACL and is defined for the unit test only.
1336 OCStackResult SetDefaultACL(OicSecAcl_t *acl)
1337 {
1338     gAcl = acl;
1339     return OC_STACK_OK;
1340 }
1341
1342 OCStackResult GetDefaultACL(OicSecAcl_t** defaultAcl)
1343 {
1344     OCStackResult ret = OC_STACK_ERROR;
1345     OicUuid_t ownerId = { .id = { 0 } };
1346     OicSecAcl_t *acl = NULL;
1347     OicSecAce_t *ace = NULL;
1348     OicSecRsrc_t* resRsrc = NULL;
1349     OicSecRsrc_t* deviceRsrc = NULL;
1350     OicSecRsrc_t* platformRsrc = NULL;
1351     OicSecRsrc_t* aclRsrc = NULL;
1352     OicSecRsrc_t* doxmRsrc = NULL;
1353     OicSecRsrc_t* pstatRsrc = NULL;
1354
1355     /*
1356      * TODO In future, when new virtual resources will be added in OIC
1357      * specification, Iotivity stack should be able to add them in
1358      * existing SVR database. To support this, we need to add 'versioning'
1359      * mechanism in SVR database.
1360      */
1361
1362     if (!defaultAcl)
1363     {
1364         return OC_STACK_INVALID_PARAM;
1365     }
1366
1367     acl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
1368     VERIFY_NON_NULL(TAG, acl, ERROR);
1369
1370     ace = (OicSecAce_t *) OICCalloc(1, sizeof(OicSecAce_t));
1371     VERIFY_NON_NULL(TAG, ace, ERROR);
1372
1373     LL_APPEND(acl->aces, ace);
1374
1375     // Subject -- Mandatory
1376     memcpy(ace->subjectuuid.id, &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t));
1377
1378     // Resources -- Mandatory
1379     // /oic/res
1380     resRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1381     VERIFY_NON_NULL(TAG, resRsrc, ERROR);
1382     LL_APPEND(ace->resources, resRsrc);
1383     resRsrc->href = OICStrdup(OC_RSRVD_WELL_KNOWN_URI);
1384     VERIFY_NON_NULL(TAG, (resRsrc->href), ERROR);
1385     resRsrc->typeLen = 1;
1386     resRsrc->types = (char**)OICCalloc(1, sizeof(char*));
1387     VERIFY_NON_NULL(TAG, resRsrc->types, ERROR);
1388     resRsrc->types[0] = OICStrdup(OC_RSRVD_RESOURCE_TYPE_RES);
1389     VERIFY_NON_NULL(TAG, resRsrc->types[0], ERROR);
1390     resRsrc->interfaceLen = 2;
1391     resRsrc->interfaces = (char**)OICCalloc(resRsrc->interfaceLen, sizeof(char*));
1392     VERIFY_NON_NULL(TAG, resRsrc->interfaces, ERROR);
1393     resRsrc->interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
1394     VERIFY_NON_NULL(TAG, resRsrc->interfaces[0], ERROR);
1395     resRsrc->interfaces[1] = OICStrdup(OC_RSRVD_INTERFACE_READ);
1396     VERIFY_NON_NULL(TAG, resRsrc->interfaces[1], ERROR);
1397
1398     // /oic/d
1399     deviceRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1400     VERIFY_NON_NULL(TAG, deviceRsrc, ERROR);
1401     LL_APPEND(ace->resources, deviceRsrc);
1402     deviceRsrc->href = OICStrdup(OC_RSRVD_DEVICE_URI);
1403     VERIFY_NON_NULL(TAG, (deviceRsrc->href), ERROR);
1404     deviceRsrc->typeLen = 1;
1405     deviceRsrc->types = (char**)OICCalloc(1, sizeof(char*));
1406     VERIFY_NON_NULL(TAG, deviceRsrc->types, ERROR);
1407     deviceRsrc->types[0] = OICStrdup(OC_RSRVD_RESOURCE_TYPE_DEVICE);
1408     VERIFY_NON_NULL(TAG, deviceRsrc->types[0], ERROR);
1409     deviceRsrc->interfaceLen = 2;
1410     deviceRsrc->interfaces = (char**)OICCalloc(deviceRsrc->interfaceLen, sizeof(char*));
1411     VERIFY_NON_NULL(TAG, deviceRsrc->interfaces, ERROR);
1412     deviceRsrc->interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
1413     VERIFY_NON_NULL(TAG, deviceRsrc->interfaces[0], ERROR);
1414     deviceRsrc->interfaces[1] = OICStrdup(OC_RSRVD_INTERFACE_READ);
1415     VERIFY_NON_NULL(TAG, deviceRsrc->interfaces[1], ERROR);
1416
1417     // /oic/p
1418     platformRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1419     VERIFY_NON_NULL(TAG, platformRsrc, ERROR);
1420     LL_APPEND(ace->resources, platformRsrc);
1421     platformRsrc->href = OICStrdup(OC_RSRVD_PLATFORM_URI);
1422     VERIFY_NON_NULL(TAG, (platformRsrc->href), ERROR);
1423     platformRsrc->typeLen = 1;
1424     platformRsrc->types = (char**)OICCalloc(1, sizeof(char*));
1425     VERIFY_NON_NULL(TAG, platformRsrc->types, ERROR);
1426     platformRsrc->types[0] = OICStrdup(OC_RSRVD_RESOURCE_TYPE_PLATFORM);
1427     VERIFY_NON_NULL(TAG, platformRsrc->types[0], ERROR);
1428     platformRsrc->interfaceLen = 2;
1429     platformRsrc->interfaces = (char**)OICCalloc(platformRsrc->interfaceLen, sizeof(char*));
1430     VERIFY_NON_NULL(TAG, platformRsrc->interfaces, ERROR);
1431     platformRsrc->interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
1432     VERIFY_NON_NULL(TAG, platformRsrc->interfaces[0], ERROR);
1433     platformRsrc->interfaces[1] = OICStrdup(OC_RSRVD_INTERFACE_READ);
1434     VERIFY_NON_NULL(TAG, platformRsrc->interfaces[1], ERROR);
1435
1436     // /oic/sec/acl
1437     aclRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1438     VERIFY_NON_NULL(TAG, aclRsrc, ERROR);
1439     LL_APPEND(ace->resources, aclRsrc);
1440     aclRsrc->href = OICStrdup(OIC_RSRC_ACL_URI);
1441     VERIFY_NON_NULL(TAG, (aclRsrc->href), ERROR);
1442     aclRsrc->typeLen = 1;
1443     aclRsrc->types = (char**)OICCalloc(1, sizeof(char*));
1444     VERIFY_NON_NULL(TAG, aclRsrc->types, ERROR);
1445     aclRsrc->types[0] = OICStrdup(OIC_RSRC_TYPE_SEC_ACL);
1446     VERIFY_NON_NULL(TAG, aclRsrc->types[0], ERROR);
1447     aclRsrc->interfaceLen = 1;
1448     aclRsrc->interfaces = (char**)OICCalloc(aclRsrc->interfaceLen, sizeof(char*));
1449     VERIFY_NON_NULL(TAG, aclRsrc->interfaces, ERROR);
1450     aclRsrc->interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
1451     VERIFY_NON_NULL(TAG, aclRsrc->interfaces[0], ERROR);
1452
1453     // /oic/sec/doxm
1454     doxmRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1455     VERIFY_NON_NULL(TAG, doxmRsrc, ERROR);
1456     LL_APPEND(ace->resources, doxmRsrc);
1457     doxmRsrc->href = OICStrdup(OIC_RSRC_DOXM_URI);
1458     VERIFY_NON_NULL(TAG, (doxmRsrc->href), ERROR);
1459     doxmRsrc->typeLen = 1;
1460     doxmRsrc->types = (char**)OICCalloc(1, sizeof(char*));
1461     VERIFY_NON_NULL(TAG, doxmRsrc->types, ERROR);
1462     doxmRsrc->types[0] = OICStrdup(OIC_RSRC_TYPE_SEC_DOXM);
1463     VERIFY_NON_NULL(TAG, doxmRsrc->types[0], ERROR);
1464     doxmRsrc->interfaceLen = 1;
1465     doxmRsrc->interfaces = (char**)OICCalloc(doxmRsrc->interfaceLen, sizeof(char*));
1466     VERIFY_NON_NULL(TAG, doxmRsrc->interfaces, ERROR);
1467     doxmRsrc->interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
1468     VERIFY_NON_NULL(TAG, doxmRsrc->interfaces[0], ERROR);
1469
1470     // /oic/sec/pstat
1471     pstatRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1472     VERIFY_NON_NULL(TAG, pstatRsrc, ERROR);
1473     LL_APPEND(ace->resources, pstatRsrc);
1474     pstatRsrc->href = OICStrdup(OIC_RSRC_PSTAT_URI);
1475     VERIFY_NON_NULL(TAG, (pstatRsrc->href), ERROR);
1476     pstatRsrc->typeLen = 1;
1477     pstatRsrc->types = (char**)OICCalloc(1, sizeof(char*));
1478     VERIFY_NON_NULL(TAG, pstatRsrc->types, ERROR);
1479     pstatRsrc->types[0] = OICStrdup(OIC_RSRC_TYPE_SEC_PSTAT);
1480     VERIFY_NON_NULL(TAG, pstatRsrc->types[0], ERROR);
1481     pstatRsrc->interfaceLen = 1;
1482     pstatRsrc->interfaces = (char**)OICCalloc(pstatRsrc->interfaceLen, sizeof(char*));
1483     VERIFY_NON_NULL(TAG, pstatRsrc->interfaces, ERROR);
1484     pstatRsrc->interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
1485     VERIFY_NON_NULL(TAG, pstatRsrc->interfaces[0], ERROR);
1486
1487     ace->permission = PERMISSION_READ;
1488     ace->validities = NULL;
1489
1490     // Device ID is the owner of this default ACL
1491     if (GetDoxmResourceData() != NULL)
1492     {
1493         ret = GetDoxmDeviceID(&ownerId);
1494         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, FATAL);
1495     }
1496     else
1497     {
1498         OCRandomUuidResult rdm = OCGenerateUuid(ownerId.id);
1499         VERIFY_SUCCESS(TAG, RAND_UUID_OK == rdm, FATAL);
1500     }
1501
1502     memcpy(&acl->rownerID, &ownerId, sizeof(OicUuid_t));
1503
1504     *defaultAcl = acl;
1505     ret = OC_STACK_OK;
1506
1507 exit:
1508
1509     if (ret != OC_STACK_OK)
1510     {
1511         DeleteACLList(acl);
1512         acl = NULL;
1513     }
1514
1515     return ret;
1516 }
1517
1518 OCStackResult InitACLResource()
1519 {
1520     OCStackResult ret = OC_STACK_ERROR;
1521
1522     uint8_t *data = NULL;
1523     size_t size = 0;
1524     ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_ACL_NAME, &data, &size);
1525     // If database read failed
1526     if (OC_STACK_OK != ret)
1527     {
1528         OIC_LOG(DEBUG, TAG, "ReadSVDataFromPS failed");
1529     }
1530     if (data)
1531     {
1532         // Read ACL resource from PS
1533         gAcl = CBORPayloadToAcl(data, size);
1534     }
1535     /*
1536      * If SVR database in persistent storage got corrupted or
1537      * is not available for some reason, a default ACL is created
1538      * which allows user to initiate ACL provisioning again.
1539      */
1540     if (!gAcl)
1541     {
1542         ret = GetDefaultACL(&gAcl);
1543         if (OC_STACK_OK != ret)
1544         {
1545             OIC_LOG(ERROR, TAG, "Failed to create default ACL");
1546         }
1547         // TODO Needs to update persistent storage
1548     }
1549     VERIFY_NON_NULL(TAG, gAcl, FATAL);
1550
1551     // Instantiate 'oic.sec.acl'
1552     ret = CreateACLResource();
1553
1554 exit:
1555     if (OC_STACK_OK != ret)
1556     {
1557         DeInitACLResource();
1558     }
1559     return ret;
1560 }
1561
1562 OCStackResult DeInitACLResource()
1563 {
1564     OCStackResult ret =  OCDeleteResource(gAclHandle);
1565     gAclHandle = NULL;
1566
1567     if (gAcl)
1568     {
1569         DeleteACLList(gAcl);
1570         gAcl = NULL;
1571     }
1572     return ret;
1573 }
1574
1575 const OicSecAce_t* GetACLResourceData(const OicUuid_t* subjectId, OicSecAce_t **savePtr)
1576 {
1577     OicSecAce_t *ace = NULL;
1578     OicSecAce_t *begin = NULL;
1579
1580     if (NULL == subjectId)
1581     {
1582         return NULL;
1583     }
1584
1585     /*
1586      * savePtr MUST point to NULL if this is the 'first' call to retrieve ACL for
1587      * subjectID.
1588      */
1589     if (NULL == *savePtr)
1590     {
1591         begin = gAcl->aces;
1592     }
1593     else
1594     {
1595         /*
1596          * If this is a 'successive' call, search for location pointed by
1597          * savePtr and assign 'begin' to the next ACL after it in the linked
1598          * list and start searching from there.
1599          */
1600         LL_FOREACH(gAcl->aces, ace)
1601         {
1602             if (ace == *savePtr)
1603             {
1604                 begin = ace->next;
1605             }
1606         }
1607     }
1608
1609     // Find the next ACL corresponding to the 'subjectID' and return it.
1610     LL_FOREACH(begin, ace)
1611     {
1612         if (memcmp(&(ace->subjectuuid), subjectId, sizeof(OicUuid_t)) == 0)
1613         {
1614             *savePtr = ace;
1615             return ace;
1616         }
1617     }
1618
1619     // Cleanup in case no ACL is found
1620     *savePtr = NULL;
1621     return NULL;
1622 }
1623
1624 OCStackResult InstallNewACL(const uint8_t *cborPayload, const size_t size)
1625 {
1626     OCStackResult ret = OC_STACK_ERROR;
1627
1628     // Convert CBOR format to ACL data. This will also validate the ACL data received.
1629     OicSecAcl_t* newAcl = CBORPayloadToAcl(cborPayload, size);
1630
1631     if (newAcl)
1632     {
1633         // Append the new ACL to existing ACL
1634         OicSecAce_t* newAce = NULL;
1635         LL_FOREACH(newAcl->aces, newAce)
1636         {
1637             LL_APPEND(gAcl->aces, newAce);
1638         }
1639
1640         size_t size = 0;
1641         uint8_t *payload = NULL;
1642         if (OC_STACK_OK == AclToCBORPayload(gAcl, &payload, &size))
1643         {
1644             if (UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, payload, size) == OC_STACK_OK)
1645             {
1646                 ret = OC_STACK_OK;
1647             }
1648             OICFree(payload);
1649         }
1650     }
1651
1652     return ret;
1653 }
1654
1655 /**
1656  * This function generates default ACE for security resource in case of owned status.
1657  *
1658  * @return Default ACE for security resource.
1659  */
1660 static OicSecAce_t* GetSecDefaultACE()
1661 {
1662     const int NUM_OF_DOXM_RT = 1;
1663     const int NUM_OF_DOXM_IF  = 1;
1664     const int NUM_OF_PSTAT_RT = 1;
1665     const int NUM_OF_PSTAT_IF = 1;
1666     const char *doxmRt[] = { OIC_RSRC_TYPE_SEC_DOXM };
1667     const char *pstatRt[] = { OIC_RSRC_TYPE_SEC_PSTAT };
1668     const char *doxmIf[] = { OC_RSRVD_INTERFACE_DEFAULT };
1669     const char *pstatIf[] = { OC_RSRVD_INTERFACE_DEFAULT };
1670     OicSecRsrc_t* doxmRsrc = NULL;
1671     OicSecRsrc_t* pstatRsrc = NULL;
1672
1673     //Generate default ACE
1674     OicSecAce_t* newAce = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
1675     VERIFY_NON_NULL(TAG, newAce, ERROR);
1676
1677     // Subject -- Mandatory
1678     memcpy(newAce->subjectuuid.id, &WILDCARD_SUBJECT_ID, WILDCARD_SUBJECT_ID_LEN);
1679
1680     //Resources -- Mandatory
1681     //Add doxm
1682     doxmRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1683     VERIFY_NON_NULL(TAG, doxmRsrc, ERROR);
1684     LL_APPEND(newAce->resources, doxmRsrc);
1685     // pstat-href
1686     doxmRsrc->href = OICStrdup(OIC_RSRC_DOXM_URI);
1687     VERIFY_NON_NULL(TAG, (doxmRsrc->href), ERROR);
1688     // pstat-rt
1689     doxmRsrc->typeLen = NUM_OF_DOXM_RT;
1690     doxmRsrc->types = (char**)OICCalloc(NUM_OF_DOXM_RT, sizeof(char*));
1691     VERIFY_NON_NULL(TAG, (doxmRsrc->types), ERROR);
1692     for(int i = 0; i < NUM_OF_DOXM_RT; i++)
1693     {
1694         doxmRsrc->types[i] = OICStrdup(doxmRt[i]);
1695         VERIFY_NON_NULL(TAG, (doxmRsrc->types[i]), ERROR);
1696     }
1697     // pstat-if
1698     doxmRsrc->interfaceLen = NUM_OF_DOXM_IF;
1699     doxmRsrc->interfaces = (char**)OICCalloc(NUM_OF_DOXM_IF, sizeof(char*));
1700     VERIFY_NON_NULL(TAG, (doxmRsrc->interfaces), ERROR);
1701     for(int i = 0; i < NUM_OF_DOXM_IF; i++)
1702     {
1703         doxmRsrc->interfaces[i] = OICStrdup(doxmIf[i]);
1704         VERIFY_NON_NULL(TAG, (doxmRsrc->interfaces[i]), ERROR);
1705     }
1706
1707     //Add pstat
1708     pstatRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1709     VERIFY_NON_NULL(TAG, pstatRsrc, ERROR);
1710     LL_APPEND(newAce->resources, pstatRsrc);
1711     //pstat-href
1712     pstatRsrc->href = OICStrdup(OIC_RSRC_PSTAT_URI);
1713     VERIFY_NON_NULL(TAG, (pstatRsrc->href), ERROR);
1714     //pstat-rt
1715     pstatRsrc->typeLen = NUM_OF_PSTAT_RT;
1716     pstatRsrc->types = (char**)OICCalloc(NUM_OF_PSTAT_RT, sizeof(char*));
1717     VERIFY_NON_NULL(TAG, (pstatRsrc->types), ERROR);
1718     for(int i = 0; i < NUM_OF_PSTAT_RT; i++)
1719     {
1720         pstatRsrc->types[i] = OICStrdup(pstatRt[i]);
1721         VERIFY_NON_NULL(TAG, (pstatRsrc->types[i]), ERROR);
1722     }
1723     // pstat-if
1724     pstatRsrc->interfaceLen = NUM_OF_PSTAT_IF;
1725     pstatRsrc->interfaces = (char**)OICCalloc(NUM_OF_PSTAT_IF, sizeof(char*));
1726     VERIFY_NON_NULL(TAG, (pstatRsrc->interfaces), ERROR);
1727     for(int i = 0; i < NUM_OF_PSTAT_IF; i++)
1728     {
1729         pstatRsrc->interfaces[i] = OICStrdup(pstatIf[i]);
1730         VERIFY_NON_NULL(TAG, (pstatRsrc->interfaces[i]), ERROR);
1731     }
1732
1733     // Permissions -- Mandatory
1734     newAce->permission = PERMISSION_READ;
1735
1736     //Period -- Not Mandatory
1737     newAce->validities = NULL;
1738
1739     return newAce;
1740 exit:
1741     FreeACE(newAce);
1742     return NULL;
1743
1744 }
1745
1746 OCStackResult UpdateDefaultSecProvACE()
1747 {
1748     OCStackResult ret = OC_STACK_OK;
1749     OicSecAce_t *ace = NULL;
1750     OicSecAce_t *tempAce = NULL;
1751
1752     if(gAcl)
1753     {
1754         int matchedRsrc = 0;
1755         bool isRemoved = false;
1756
1757         LL_FOREACH_SAFE(gAcl->aces, ace, tempAce)
1758         {
1759             //Find default security resource ACL
1760             if(memcmp(&ace->subjectuuid, &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t)) == 0 &&
1761                 ((PERMISSION_READ | PERMISSION_WRITE) == ace->permission))
1762             {
1763                 matchedRsrc = 0;
1764
1765                 OicSecRsrc_t* rsrc = NULL;
1766                 LL_FOREACH(ace->resources, rsrc)
1767                 {
1768                     if(strncmp(rsrc->href, OIC_RSRC_DOXM_URI,
1769                                strlen(OIC_RSRC_DOXM_URI) + 1) == 0 ||
1770                        strncmp(rsrc->href, OIC_RSRC_CRED_URI,
1771                                strlen(OIC_RSRC_CRED_URI) + 1) == 0 ||
1772                        strncmp(rsrc->href, OIC_RSRC_ACL_URI,
1773                                strlen(OIC_RSRC_ACL_URI) + 1) == 0 ||
1774                        strncmp(rsrc->href, OIC_RSRC_PSTAT_URI,
1775                                strlen(OIC_RSRC_PSTAT_URI) + 1) == 0)
1776                     {
1777                         matchedRsrc++;
1778                     }
1779                 }
1780
1781                 //If default security resource ACL is detected, delete it.
1782                 if(NUMBER_OF_SEC_PROV_RSCS == matchedRsrc)
1783                 {
1784                     LL_DELETE(gAcl->aces, ace);
1785                     FreeACE(ace);
1786                     isRemoved = true;
1787                 }
1788             }
1789         }
1790
1791         if(isRemoved)
1792         {
1793             /*
1794              * Generate new security resource ACE as follows :
1795              *      subject : "*"
1796              *      resources :  '/oic/sec/doxm', '/oic/sec/pstat'
1797              *      permission : READ
1798              */
1799             OicSecAce_t *secDefaultAce = GetSecDefaultACE();
1800             if (secDefaultAce)
1801             {
1802                 LL_APPEND(gAcl->aces, secDefaultAce);
1803
1804                 size_t size = 0;
1805                 uint8_t *payload = NULL;
1806                 if (OC_STACK_OK == AclToCBORPayload(gAcl, &payload, &size))
1807                 {
1808                     if (UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, payload, size) == OC_STACK_OK)
1809                     {
1810                         ret = OC_STACK_OK;
1811                     }
1812                     OICFree(payload);
1813                 }
1814             }
1815         }
1816     }
1817
1818     return ret;
1819 }
1820
1821 OCStackResult SetAclRownerId(const OicUuid_t* newROwner)
1822 {
1823     OCStackResult ret = OC_STACK_ERROR;
1824     uint8_t *cborPayload = NULL;
1825     size_t size = 0;
1826     OicUuid_t prevId = {.id={0}};
1827
1828     if(NULL == newROwner)
1829     {
1830         ret = OC_STACK_INVALID_PARAM;
1831     }
1832     if(NULL == gAcl)
1833     {
1834         ret = OC_STACK_NO_RESOURCE;
1835     }
1836
1837     if(newROwner && gAcl)
1838     {
1839         memcpy(prevId.id, gAcl->rownerID.id, sizeof(prevId.id));
1840         memcpy(gAcl->rownerID.id, newROwner->id, sizeof(newROwner->id));
1841
1842         ret = AclToCBORPayload(gAcl, &cborPayload, &size);
1843         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1844
1845         ret = UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, cborPayload, size);
1846         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1847
1848         OICFree(cborPayload);
1849     }
1850
1851     return ret;
1852
1853 exit:
1854     OICFree(cborPayload);
1855     memcpy(gAcl->rownerID.id, prevId.id, sizeof(prevId.id));
1856     return ret;
1857 }
1858
1859 OCStackResult GetAclRownerId(OicUuid_t *rowneruuid)
1860 {
1861     OCStackResult retVal = OC_STACK_ERROR;
1862     if (gAcl)
1863     {
1864         *rowneruuid = gAcl->rownerID;
1865         retVal = OC_STACK_OK;
1866     }
1867     return retVal;
1868 }