1 //******************************************************************
3 // Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
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
11 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21 #include "gtest/gtest.h"
22 #include <coap/utlist.h>
25 #include "psinterface.h"
26 #include "ocpayload.h"
27 #include "oic_malloc.h"
28 #include "oic_string.h"
29 #include "cainterface.h"
30 #include "secureresourcemanager.h"
31 #include "securevirtualresourcetypes.h"
32 #include "srmresourcestrings.h"
33 #include "aclresource.h"
34 #include "srmtestcommon.h"
35 #include "srmutility.h"
37 #include "doxmresource.h"
38 #include "ocpayload.h"
39 #include "ocpayloadcbor.h"
40 #include "payload_logging.h"
41 #include "security_internals.h"
45 #define TAG "SRM-ACL-UT"
47 // These paths match jenkins build configuration.
48 const char* DEFAULT_ACL_FILE_NAME = "oic_unittest_default_acl.dat";
49 const char* ACL1_FILE_NAME = "oic_unittest_acl1.dat";
51 #define NUM_ACE_FOR_WILDCARD_IN_ACL1_DAT (1)
53 static bool AddResourceToACE(OicSecAce_t* ace, const char* rsrcName,
54 const char* typeName, const char* interfaceName)
56 OicSecRsrc_t* rsrc = NULL;
58 VERIFY_NON_NULL(TAG, ace, ERROR);
59 VERIFY_NON_NULL(TAG, rsrcName, ERROR);
60 VERIFY_NON_NULL(TAG, interfaceName, ERROR);
61 VERIFY_NON_NULL(TAG, typeName, ERROR);
63 rsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
64 VERIFY_NON_NULL(TAG, rsrc, ERROR);
65 rsrc->href = OICStrdup(rsrcName);
66 VERIFY_NON_NULL(TAG, rsrc->href, ERROR);
69 rsrc->types = (char**)OICCalloc(1, sizeof(char*));
70 VERIFY_NON_NULL(TAG, rsrc->types, ERROR);
71 rsrc->types[0] = OICStrdup(typeName);
72 VERIFY_NON_NULL(TAG, rsrc->types[0], ERROR);
74 rsrc->interfaceLen = 1;
75 rsrc->interfaces = (char**)OICCalloc(1, sizeof(char*));
76 VERIFY_NON_NULL(TAG, rsrc->interfaces, ERROR);
77 rsrc->interfaces[0] = OICStrdup(interfaceName);
78 VERIFY_NON_NULL(TAG, rsrc->interfaces[0], ERROR);
80 LL_APPEND(ace->resources, rsrc);
88 OICFree(rsrc->types[0]);
90 OICFree(rsrc->interfaces[0]);
91 OICFree(rsrc->interfaces);
98 static int GetNumberOfResource(const OicSecAce_t* ace)
101 OicSecRsrc_t* rsrc = NULL;
102 LL_FOREACH(ace->resources, rsrc)
110 TEST(ACLResourceTest, CBORDefaultACLConversion)
112 uint8_t defaultAclSub[] = { 0x2a };
113 uint8_t defaultAclOwnrs[] = {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
114 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32};
116 OicSecAcl_t *defaultAcl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
117 ASSERT_TRUE(NULL != defaultAcl);
118 OicSecAce_t *ace = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
119 ASSERT_TRUE(NULL != ace);
121 memcpy(ace->subjectuuid.id, defaultAclSub, sizeof(defaultAclSub));
122 LL_APPEND(defaultAcl->aces, ace);
124 EXPECT_EQ(true, AddResourceToACE(ace, "/oic/res", "oic.wk.res", "oic.if.ll"));
125 EXPECT_EQ(true, AddResourceToACE(ace, "/oic/d", "oic.wk.d", "oic.if.r"));
126 EXPECT_EQ(true, AddResourceToACE(ace, "/oic/p", "oic.wk.p", "oic.if.r"));
127 EXPECT_EQ(true, AddResourceToACE(ace, "/oic/res/types/d", "oic.wk.unknow", "oic.if.r"));
128 EXPECT_EQ(true, AddResourceToACE(ace, "/oic/ad", "oic.wk.ad", "oic.if.baseline"));
129 EXPECT_EQ(true, AddResourceToACE(ace, "/oic/sec/acl", "oic.r.acl", "oic.if.baseline"));
130 EXPECT_EQ(true, AddResourceToACE(ace, "/oic/sec/doxm", "oic.r.doxm" ,"oic.if.baseline"));
131 EXPECT_EQ(true, AddResourceToACE(ace, "/oic/sec/pstat", "oic.r.pstat" ,"oic.if.baseline"));
133 memcpy(defaultAcl->rownerID.id, defaultAclOwnrs, sizeof(defaultAclOwnrs));
135 size_t defaultAclSize = 0;
136 uint8_t *defaultPsStorage = NULL;
137 OCStackResult convRet = AclToCBORPayload(defaultAcl, &defaultPsStorage, &defaultAclSize);
138 EXPECT_EQ(OC_STACK_OK, convRet);
139 ASSERT_TRUE(NULL != defaultPsStorage);
140 EXPECT_NE(0, defaultAclSize);
142 OicSecAcl_t* convertedAcl = CBORPayloadToAcl(defaultPsStorage, defaultAclSize);
143 ASSERT_TRUE(NULL != convertedAcl);
147 OicSecAce_t* tempAce = NULL;
148 LL_FOREACH(defaultAcl->aces, tempAce)
150 rsrcCnt1 += GetNumberOfResource(tempAce);
153 LL_FOREACH(convertedAcl->aces, tempAce)
155 rsrcCnt2 += GetNumberOfResource(tempAce);
157 EXPECT_EQ(rsrcCnt1, rsrcCnt2);
159 DeleteACLList(convertedAcl);
160 DeleteACLList(defaultAcl);
161 OICFree(defaultPsStorage);
164 TEST(ACLResourceTest, CBORACLConversion)
166 uint8_t ownrs[] = {0x32, 0x32, 0x32, 0x32,
167 0x32, 0x32, 0x32, 0x32,
168 0x32, 0x32, 0x32, 0x32,
169 0x32, 0x32, 0x32, 0x32};
170 const char* subjectUuid[3] = {"0000000000000000",
173 const uint16_t permission[3] = {2, 6, 31};
174 const size_t numOfRsrc[3] = {6, 2, 2};
176 OicSecAcl_t *secAcl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
177 ASSERT_TRUE(secAcl != NULL);
178 memcpy(secAcl->rownerID.id, ownrs, sizeof(ownrs));
180 OicSecAce_t *ace = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
181 ASSERT_TRUE(NULL != ace);
182 ace->permission = permission[0];
183 memcpy(ace->subjectuuid.id, subjectUuid[0], UUID_LENGTH);
184 EXPECT_EQ(true, AddResourceToACE(ace, "/oic/res", "oic.wk.res", "oic.if.ll"));
185 EXPECT_EQ(true, AddResourceToACE(ace, "/oic/d", "oic.wk.d", "oic.if.r"));
186 EXPECT_EQ(true, AddResourceToACE(ace, "/oic/p", "oic.wk.p", "oic.if.r"));
187 EXPECT_EQ(true, AddResourceToACE(ace, "/oic/res/types/d", "oic.wk.unknow", "oic.if.r"));
188 EXPECT_EQ(true, AddResourceToACE(ace, "/oic/ad", "oic.wk.ad", "oic.if.baseline"));
189 EXPECT_EQ(true, AddResourceToACE(ace, "/oic/sec/acl", "oic.r.acl", "oic.if.baseline"));
190 LL_APPEND(secAcl->aces, ace);
192 OicSecAce_t *ace1 = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
193 ASSERT_TRUE(NULL != ace1);
194 ace1->permission = permission[1];
195 memcpy(ace1->subjectuuid.id, subjectUuid[1], UUID_LENGTH);
196 EXPECT_EQ(true, AddResourceToACE(ace1, "/oic/sec/doxm", "oic.r.doxm" ,"oic.if.baseline"));
197 EXPECT_EQ(true, AddResourceToACE(ace1, "/oic/sec/pstat", "oic.r.pstat" ,"oic.if.baseline"));
198 LL_APPEND(secAcl->aces, ace1);
200 OicSecAce_t *ace2 = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
201 ASSERT_TRUE(NULL != ace2);
202 ace2->permission = permission[2];
203 memcpy(ace2->subjectuuid.id, subjectUuid[2], UUID_LENGTH);
204 EXPECT_EQ(true, AddResourceToACE(ace2, "/oic/light", "oic.core", "oic.if.baseline"));
205 EXPECT_EQ(true, AddResourceToACE(ace2, "/oic/garage", "oic.core", "oic.if.baseline"));
206 LL_APPEND(secAcl->aces, ace2);
209 uint8_t *psStorage = NULL;
210 EXPECT_EQ(OC_STACK_OK, AclToCBORPayload(secAcl, &psStorage, &size));
211 ASSERT_TRUE(NULL != psStorage);
212 OicSecAcl_t *acl = CBORPayloadToAcl(psStorage, size);
213 ASSERT_TRUE(NULL != acl);
215 size_t numberOfCheckedAce = 0;
216 OicSecAce_t* tempAce = NULL;
217 LL_FOREACH(acl->aces, tempAce)
219 if(memcmp(tempAce->subjectuuid.id, subjectUuid[0], strlen(subjectUuid[0])) == 0)
221 EXPECT_EQ(numOfRsrc[0], GetNumberOfResource(tempAce));
222 EXPECT_EQ(permission[0], tempAce->permission);
223 numberOfCheckedAce++;
225 if(memcmp(tempAce->subjectuuid.id, subjectUuid[1], strlen(subjectUuid[1])) == 0)
227 EXPECT_EQ(numOfRsrc[1], GetNumberOfResource(tempAce));
228 EXPECT_EQ(permission[1], tempAce->permission);
229 numberOfCheckedAce++;
231 if(memcmp(tempAce->subjectuuid.id, subjectUuid[2], strlen(subjectUuid[2])) == 0)
233 EXPECT_EQ(numOfRsrc[2], GetNumberOfResource(tempAce));
234 EXPECT_EQ(permission[2], tempAce->permission);
235 numberOfCheckedAce++;
238 EXPECT_EQ(3, numberOfCheckedAce);
241 DeleteACLList(secAcl);
246 TEST(ACLResourceTest, InitAclResource)
248 EXPECT_EQ(OC_STACK_INVALID_PARAM, InitACLResource());
249 EXPECT_EQ(OC_STACK_INVALID_PARAM, DeInitACLResource());
253 TEST(ACLResourceTest, GetDefaultACLTests)
255 uint8_t *payload = NULL;
258 ASSERT_TRUE(ReadCBORFile(DEFAULT_ACL_FILE_NAME, OIC_JSON_ACL_NAME, &payload, &size));
259 ASSERT_TRUE(NULL != payload);
261 OicSecAcl_t *psAcl = CBORPayloadToAcl(payload, size);
262 ASSERT_TRUE(NULL != psAcl);
264 OicSecAcl_t *acl = NULL;
265 EXPECT_EQ(OC_STACK_OK, GetDefaultACL(&acl));
266 ASSERT_TRUE(NULL != acl);
268 // Verify if the SRM generated default ACL matches with unit test default
271 OicSecAce_t* tempAce1 = NULL;
272 OicSecAce_t* tempAce2 = NULL;
274 for(tempAce1 = acl->aces, tempAce2 = psAcl->aces;
275 tempAce1 && tempAce2; tempAce1 = tempAce1->next,
276 tempAce2 = tempAce2->next)
278 EXPECT_TRUE(memcmp(tempAce1->subjectuuid.id, tempAce2->subjectuuid.id, sizeof(tempAce1->subjectuuid.id)) == 0);
279 EXPECT_EQ(tempAce1->permission, tempAce2->permission);
280 EXPECT_EQ(GetNumberOfResource(tempAce1), GetNumberOfResource(tempAce2));
284 DeleteACLList(psAcl);
291 TEST(ACLResourceTest, ACLPostTest)
293 // Read an ACL from the file
294 uint8_t *payload = NULL;
297 static OCPersistentStorage ps = OCPersistentStorage();
298 SetPersistentHandler(&ps, true);
300 OicSecAcl_t *defaultAcl = NULL;
301 EXPECT_EQ(OC_STACK_OK, GetDefaultACL(&defaultAcl));
302 ASSERT_TRUE(defaultAcl != NULL);
303 EXPECT_EQ(OC_STACK_OK, SetDefaultACL(defaultAcl));
305 ASSERT_TRUE(ReadCBORFile(ACL1_FILE_NAME, OIC_JSON_ACL_NAME, &payload, &size));
306 ASSERT_TRUE(NULL != payload);
308 OCSecurityPayload *securityPayload = OCSecurityPayloadCreate(payload, size);
309 ASSERT_TRUE(NULL != securityPayload);
311 // Create Entity Handler POST request payload
312 OCEntityHandlerRequest ehReq = OCEntityHandlerRequest();
313 ehReq.method = OC_REST_POST;
314 ehReq.payload = (OCPayload *) securityPayload;
316 ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
318 OicSecAcl_t *acl = CBORPayloadToAcl(payload, size);
319 ASSERT_TRUE(NULL != acl);
321 // Verify if SRM contains ACL for the subject
322 OicSecAce_t *savePtr = NULL;
323 const OicSecAce_t* subjectAcl = GetACLResourceData(&(acl->aces->subjectuuid), &savePtr);
324 ASSERT_TRUE(NULL != subjectAcl);
328 OCPayloadDestroy((OCPayload *) securityPayload);
334 // gAcl is a pointer to the the global ACL used by SRM
335 extern OicSecAcl_t *gAcl;
338 // GetACLResource tests
339 TEST(ACLResourceTest, GetACLResourceTests)
341 // Read an ACL from the file
342 static OCPersistentStorage ps = OCPersistentStorage();
343 SetPersistentHandler(&ps, true);
345 uint8_t *payload = NULL;
348 ASSERT_TRUE(ReadCBORFile(ACL1_FILE_NAME, OIC_JSON_ACL_NAME, &payload, &size));
349 ASSERT_TRUE(payload != NULL);
351 OicSecAcl_t *defaultPsAcl = CBORPayloadToAcl(payload, size);
352 ASSERT_TRUE(defaultPsAcl != NULL);
354 OicSecAcl_t *acl1 = NULL;
355 EXPECT_EQ(OC_STACK_OK, GetDefaultACL(&acl1));
356 ASSERT_TRUE(acl1 != NULL);
357 EXPECT_EQ(OC_STACK_OK, SetDefaultACL(acl1));
359 // Verify that ACL file contains 2 ACE entries for 'WILDCARD' subject
360 const OicSecAce_t *ace = NULL;
361 OicSecAce_t *savePtr = NULL;
362 OicUuid_t subject = WILDCARD_SUBJECT_ID;
367 ace = GetACLResourceData(&subject, &savePtr);
368 count = (NULL != ace) ? count + 1 : count;
369 } while (ace != NULL);
371 EXPECT_EQ(count, NUM_ACE_FOR_WILDCARD_IN_ACL1_DAT);
373 /* Perform cleanup */
375 DeleteACLList(defaultPsAcl);
379 static OCStackResult populateAcl(OicSecAcl_t *acl, int numRsrc)
381 OCStackResult ret = OC_STACK_ERROR;
382 OicSecAce_t* ace = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
383 VERIFY_NON_NULL(TAG, ace, ERROR);
385 memcpy(ace->subjectuuid.id, "2222222222222222", sizeof(ace->subjectuuid.id));
386 EXPECT_EQ(true, AddResourceToACE(ace, "/a/led", "oic.core", "oic.if.r"));
389 EXPECT_EQ(true, AddResourceToACE(ace, "/a/fan", "oic.core", "oic.if.r"));
392 LL_APPEND(acl->aces, ace);
394 memcpy(acl->rownerID.id, "1111111111111111", sizeof(acl->rownerID.id));
405 TEST(ACLResourceTest, ACLDeleteWithSingleResourceTest)
407 static OCPersistentStorage ps = OCPersistentStorage();
408 SetPersistentHandler(&ps, true);
410 OicSecAcl_t *defaultAcl = NULL;
411 EXPECT_EQ(OC_STACK_OK, GetDefaultACL(&defaultAcl));
412 ASSERT_TRUE(defaultAcl != NULL);
413 EXPECT_EQ(OC_STACK_OK, SetDefaultACL(defaultAcl));
416 OicSecAcl_t acl = OicSecAcl_t();
417 EXPECT_EQ(OC_STACK_OK, populateAcl(&acl, 1));
419 //GET CBOR POST payload
421 uint8_t *payload = NULL;
422 EXPECT_EQ(OC_STACK_OK, AclToCBORPayload(&acl, &payload, &size));
423 ASSERT_TRUE(NULL != payload);
426 OCSecurityPayload *securityPayload = OCSecurityPayloadCreate(payload, size);
427 ASSERT_TRUE(NULL != securityPayload);
429 // Create Entity Handler POST request payload
430 OCEntityHandlerRequest ehReq = OCEntityHandlerRequest();
431 ehReq.payload = (OCPayload *) securityPayload;
432 ehReq.method = OC_REST_POST;
433 ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
435 // Verify if SRM contains ACE for the subject
436 OicSecAce_t* savePtr = NULL;
437 const OicSecAce_t* subjectAce1 = GetACLResourceData(&acl.aces->subjectuuid, &savePtr);
438 ASSERT_TRUE(NULL != subjectAce1);
440 // Create Entity Handler DELETE request
441 ehReq.method = OC_REST_DELETE;
442 char query[] = "subjectuuid=32323232-3232-3232-3232-323232323232;resources=/a/led";
443 ehReq.query = (char *)OICMalloc(strlen(query)+1);
444 ASSERT_TRUE(NULL != ehReq.query);
445 OICStrcpy(ehReq.query, strlen(query)+1, query);
446 ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
448 // Verify if SRM has deleted ACE for the subject
450 const OicSecAce_t* subjectAce2 = GetACLResourceData(&acl.aces->subjectuuid, &savePtr);
451 ASSERT_TRUE(NULL == subjectAce2);
455 OICFree(ehReq.query);
456 OCPayloadDestroy((OCPayload *)securityPayload);
460 TEST(ACLResourceTest, ACLDeleteWithMultiResourceTest)
462 static OCPersistentStorage ps = OCPersistentStorage();
463 SetPersistentHandler(&ps, true);
465 OicSecAcl_t *defaultAcl = NULL;
466 EXPECT_EQ(OC_STACK_OK, GetDefaultACL(&defaultAcl));
467 ASSERT_TRUE(defaultAcl != NULL);
468 EXPECT_EQ(OC_STACK_OK, SetDefaultACL(defaultAcl));
471 OicSecAcl_t acl = OicSecAcl_t();
472 EXPECT_EQ(OC_STACK_OK, populateAcl(&acl, 2));
474 //GET CBOR POST payload
476 uint8_t *payload = NULL;
477 EXPECT_EQ(OC_STACK_OK, AclToCBORPayload(&acl, &payload, &size));
478 ASSERT_TRUE(NULL != payload);
481 OCSecurityPayload *securityPayload = OCSecurityPayloadCreate(payload, size);
482 ASSERT_TRUE(NULL!= securityPayload);
484 // Create Entity Handler POST request payload
485 OCEntityHandlerRequest ehReq = OCEntityHandlerRequest();
486 ehReq.method = OC_REST_POST;
487 ehReq.payload = (OCPayload *)securityPayload;
488 ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
490 // Verify if SRM contains ACE for the subject with two resources
491 OicSecAce_t* savePtr = NULL;
492 const OicSecAce_t* subjectAce1 = GetACLResourceData(&acl.aces->subjectuuid, &savePtr);
493 ASSERT_TRUE(NULL != subjectAce1);
494 EXPECT_EQ(2, GetNumberOfResource(subjectAce1));
497 OicSecRsrc_t* rsrc = NULL;
498 LL_FOREACH(subjectAce1->resources, rsrc)
500 printf("%s\n", rsrc->href);
504 // Create Entity Handler DELETE request
505 ehReq.method = OC_REST_DELETE;
506 char query[] = "subjectuuid=32323232-3232-3232-3232-323232323232;resources=/a/led";
507 ehReq.query = (char *)OICMalloc(strlen(query)+1);
508 ASSERT_TRUE(NULL != ehReq.query);
509 OICStrcpy(ehReq.query, strlen(query)+1, query);
511 ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
513 // Verify if SRM contains ACL for the subject but only with one resource
515 const OicSecAce_t* subjectAce2 = GetACLResourceData(&acl.aces->subjectuuid, &savePtr);
516 ASSERT_TRUE(NULL != subjectAce2);
517 EXPECT_EQ(1, GetNumberOfResource(subjectAce2));
520 OCPayloadDestroy((OCPayload *)securityPayload);
522 OICFree(ehReq.query);
526 //'GET' with query ACL test
527 TEST(ACLResourceTest, ACLGetWithQueryTest)
529 static OCPersistentStorage ps = OCPersistentStorage();
530 SetPersistentHandler(&ps, true);
532 OicSecAcl_t *defaultAcl = NULL;
533 EXPECT_EQ(OC_STACK_OK, GetDefaultACL(&defaultAcl));
534 ASSERT_TRUE(defaultAcl != NULL);
535 EXPECT_EQ(OC_STACK_OK, SetDefaultACL(defaultAcl));
538 OicSecAcl_t acl = OicSecAcl_t();
539 EXPECT_EQ(OC_STACK_OK, populateAcl(&acl, 1));
541 //GET CBOR POST payload
543 uint8_t *payload = NULL;
544 EXPECT_EQ(OC_STACK_OK, AclToCBORPayload(&acl, &payload, &size));
545 ASSERT_TRUE(NULL != payload);
548 OCSecurityPayload *securityPayload = OCSecurityPayloadCreate(payload, size);
549 ASSERT_TRUE(NULL != securityPayload);
551 //Create Entity Handler POST request payload
552 OCEntityHandlerRequest ehReq = OCEntityHandlerRequest();
553 ehReq.method = OC_REST_POST;
554 ehReq.payload = (OCPayload *)securityPayload;
555 ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
557 //Create Entity Handler GET request wit query
558 ehReq.method = OC_REST_GET;
559 char query[] = "subjectuuid=32323232-3232-3232-3232-323232323232;resources=/a/led";
560 ehReq.query = (char*)OICMalloc(strlen(query)+1);
561 ASSERT_TRUE(NULL != ehReq.query);
562 OICStrcpy(ehReq.query, strlen(query)+1, query);
564 ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
567 OCPayloadDestroy((OCPayload *)securityPayload);
569 OICFree(ehReq.query);