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"
24 #include <linux/limits.h>
28 #include "psinterface.h"
29 #include "ocpayload.h"
30 #include "oic_malloc.h"
31 #include "oic_string.h"
32 #include "cainterface.h"
33 #include "secureresourcemanager.h"
34 #include "securevirtualresourcetypes.h"
35 #include "srmresourcestrings.h"
36 #include "aclresource.h"
37 #include "srmtestcommon.h"
38 #include "srmutility.h"
40 #include "doxmresource.h"
41 #include "ocpayload.h"
42 #include "ocpayloadcbor.h"
43 #include "payload_logging.h"
44 #include "security_internals.h"
48 #define TAG "SRM-ACL-UT"
50 // These paths match jenkins build configuration.
51 const char* DEFAULT_ACL_FILE_NAME = "/oic_unittest_default_acl.dat";
52 const char* ACL1_FILE_NAME = "/oic_unittest_acl1.dat";
54 #define NUM_ACE_FOR_WILDCARD_IN_ACL1_DAT (1)
56 static bool AddResourceToACE(OicSecAce_t* ace, const char* rsrcName,
57 const char* typeName, const char* interfaceName)
59 OicSecRsrc_t* rsrc = NULL;
61 VERIFY_NON_NULL(TAG, ace, ERROR);
62 VERIFY_NON_NULL(TAG, rsrcName, ERROR);
63 VERIFY_NON_NULL(TAG, interfaceName, ERROR);
64 VERIFY_NON_NULL(TAG, typeName, ERROR);
66 rsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
67 VERIFY_NON_NULL(TAG, rsrc, ERROR);
68 rsrc->href = OICStrdup(rsrcName);
69 VERIFY_NON_NULL(TAG, rsrc->href, ERROR);
72 rsrc->types = (char**)OICCalloc(1, sizeof(char*));
73 VERIFY_NON_NULL(TAG, rsrc->types, ERROR);
74 rsrc->types[0] = OICStrdup(typeName);
75 VERIFY_NON_NULL(TAG, rsrc->types[0], ERROR);
77 rsrc->interfaceLen = 1;
78 rsrc->interfaces = (char**)OICCalloc(1, sizeof(char*));
79 VERIFY_NON_NULL(TAG, rsrc->interfaces, ERROR);
80 rsrc->interfaces[0] = OICStrdup(interfaceName);
81 VERIFY_NON_NULL(TAG, rsrc->interfaces[0], ERROR);
83 LL_APPEND(ace->resources, rsrc);
91 OICFree(rsrc->types[0]);
93 OICFree(rsrc->interfaces[0]);
94 OICFree(rsrc->interfaces);
101 static int GetNumberOfResource(const OicSecAce_t* ace)
104 OicSecRsrc_t* rsrc = NULL;
105 LL_FOREACH(ace->resources, rsrc)
113 TEST(ACLResourceTest, CBORDefaultACLConversion)
115 uint8_t defaultAclSub[] = { 0x2a };
116 uint8_t defaultAclOwnrs[] = {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
117 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32};
119 OicSecAcl_t *defaultAcl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
120 ASSERT_TRUE(NULL != defaultAcl);
121 OicSecAce_t *ace = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
122 ASSERT_TRUE(NULL != ace);
124 memcpy(ace->subjectuuid.id, defaultAclSub, sizeof(defaultAclSub));
125 LL_APPEND(defaultAcl->aces, ace);
127 EXPECT_EQ(true, AddResourceToACE(ace, "/oic/res", "oic.wk.res", "oic.if.ll"));
128 EXPECT_EQ(true, AddResourceToACE(ace, "/oic/d", "oic.wk.d", "oic.if.r"));
129 EXPECT_EQ(true, AddResourceToACE(ace, "/oic/p", "oic.wk.p", "oic.if.r"));
130 EXPECT_EQ(true, AddResourceToACE(ace, "/oic/res/types/d", "oic.wk.unknow", "oic.if.r"));
131 EXPECT_EQ(true, AddResourceToACE(ace, "/oic/ad", "oic.wk.ad", "oic.if.baseline"));
132 EXPECT_EQ(true, AddResourceToACE(ace, "/oic/sec/acl", "oic.r.acl", "oic.if.baseline"));
133 EXPECT_EQ(true, AddResourceToACE(ace, "/oic/sec/doxm", "oic.r.doxm" ,"oic.if.baseline"));
134 EXPECT_EQ(true, AddResourceToACE(ace, "/oic/sec/pstat", "oic.r.pstat" ,"oic.if.baseline"));
136 memcpy(defaultAcl->rownerID.id, defaultAclOwnrs, sizeof(defaultAclOwnrs));
138 size_t defaultAclSize = 0;
139 uint8_t *defaultPsStorage = NULL;
140 OCStackResult convRet = AclToCBORPayload(defaultAcl, &defaultPsStorage, &defaultAclSize);
141 EXPECT_EQ(OC_STACK_OK, convRet);
142 ASSERT_TRUE(NULL != defaultPsStorage);
143 EXPECT_NE(0, defaultAclSize);
145 OicSecAcl_t* convertedAcl = CBORPayloadToAcl(defaultPsStorage, defaultAclSize);
146 ASSERT_TRUE(NULL != convertedAcl);
150 OicSecAce_t* tempAce = NULL;
151 LL_FOREACH(defaultAcl->aces, tempAce)
153 rsrcCnt1 += GetNumberOfResource(tempAce);
156 LL_FOREACH(convertedAcl->aces, tempAce)
158 rsrcCnt2 += GetNumberOfResource(tempAce);
160 EXPECT_EQ(rsrcCnt1, rsrcCnt2);
162 DeleteACLList(convertedAcl);
163 DeleteACLList(defaultAcl);
164 OICFree(defaultPsStorage);
167 TEST(ACLResourceTest, CBORACLConversion)
169 uint8_t ownrs[] = {0x32, 0x32, 0x32, 0x32,
170 0x32, 0x32, 0x32, 0x32,
171 0x32, 0x32, 0x32, 0x32,
172 0x32, 0x32, 0x32, 0x32};
173 const char* subjectUuid[3] = {"0000000000000000",
176 const uint16_t permission[3] = {2, 6, 31};
177 const size_t numOfRsrc[3] = {6, 2, 2};
179 OicSecAcl_t *secAcl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
180 ASSERT_TRUE(secAcl != NULL);
181 memcpy(secAcl->rownerID.id, ownrs, sizeof(ownrs));
183 OicSecAce_t *ace = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
184 ASSERT_TRUE(NULL != ace);
185 ace->permission = permission[0];
186 memcpy(ace->subjectuuid.id, subjectUuid[0], strlen(subjectUuid[0]));
187 EXPECT_EQ(true, AddResourceToACE(ace, "/oic/res", "oic.wk.res", "oic.if.ll"));
188 EXPECT_EQ(true, AddResourceToACE(ace, "/oic/d", "oic.wk.d", "oic.if.r"));
189 EXPECT_EQ(true, AddResourceToACE(ace, "/oic/p", "oic.wk.p", "oic.if.r"));
190 EXPECT_EQ(true, AddResourceToACE(ace, "/oic/res/types/d", "oic.wk.unknow", "oic.if.r"));
191 EXPECT_EQ(true, AddResourceToACE(ace, "/oic/ad", "oic.wk.ad", "oic.if.baseline"));
192 EXPECT_EQ(true, AddResourceToACE(ace, "/oic/sec/acl", "oic.r.acl", "oic.if.baseline"));
193 LL_APPEND(secAcl->aces, ace);
195 OicSecAce_t *ace1 = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
196 ASSERT_TRUE(NULL != ace1);
197 ace1->permission = permission[1];
198 memcpy(ace1->subjectuuid.id, subjectUuid[1], strlen(subjectUuid[1]));
199 EXPECT_EQ(true, AddResourceToACE(ace1, "/oic/sec/doxm", "oic.r.doxm" ,"oic.if.baseline"));
200 EXPECT_EQ(true, AddResourceToACE(ace1, "/oic/sec/pstat", "oic.r.pstat" ,"oic.if.baseline"));
201 LL_APPEND(secAcl->aces, ace1);
203 OicSecAce_t *ace2 = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
204 ASSERT_TRUE(NULL != ace2);
205 ace2->permission = permission[2];
206 memcpy(ace2->subjectuuid.id, subjectUuid[2], strlen(subjectUuid[2]));
207 EXPECT_EQ(true, AddResourceToACE(ace2, "/oic/light", "oic.core", "oic.if.baseline"));
208 EXPECT_EQ(true, AddResourceToACE(ace2, "/oic/garage", "oic.core", "oic.if.baseline"));
209 LL_APPEND(secAcl->aces, ace2);
212 uint8_t *psStorage = NULL;
213 EXPECT_EQ(OC_STACK_OK, AclToCBORPayload(secAcl, &psStorage, &size));
214 ASSERT_TRUE(NULL != psStorage);
215 OicSecAcl_t *acl = CBORPayloadToAcl(psStorage, size);
216 ASSERT_TRUE(NULL != acl);
218 size_t numberOfCheckedAce = 0;
219 OicSecAce_t* tempAce = NULL;
220 LL_FOREACH(acl->aces, tempAce)
222 if(memcmp(tempAce->subjectuuid.id, subjectUuid[0], strlen(subjectUuid[0])) == 0)
224 EXPECT_EQ(numOfRsrc[0], GetNumberOfResource(tempAce));
225 EXPECT_EQ(permission[0], tempAce->permission);
226 numberOfCheckedAce++;
228 if(memcmp(tempAce->subjectuuid.id, subjectUuid[1], strlen(subjectUuid[1])) == 0)
230 EXPECT_EQ(numOfRsrc[1], GetNumberOfResource(tempAce));
231 EXPECT_EQ(permission[1], tempAce->permission);
232 numberOfCheckedAce++;
234 if(memcmp(tempAce->subjectuuid.id, subjectUuid[2], strlen(subjectUuid[2])) == 0)
236 EXPECT_EQ(numOfRsrc[2], GetNumberOfResource(tempAce));
237 EXPECT_EQ(permission[2], tempAce->permission);
238 numberOfCheckedAce++;
241 EXPECT_EQ(3, numberOfCheckedAce);
244 DeleteACLList(secAcl);
249 TEST(ACLResourceTest, InitAclResource)
251 EXPECT_EQ(OC_STACK_INVALID_PARAM, InitACLResource());
252 EXPECT_EQ(OC_STACK_INVALID_PARAM, DeInitACLResource());
256 TEST(ACLResourceTest, GetDefaultACLTests)
258 uint8_t *payload = NULL;
261 ASSERT_TRUE(ReadCBORFile(DEFAULT_ACL_FILE_NAME, OIC_JSON_ACL_NAME, &payload, &size));
262 ASSERT_TRUE(NULL != payload);
264 OicSecAcl_t *psAcl = CBORPayloadToAcl(payload, size);
265 ASSERT_TRUE(NULL != psAcl);
267 OicSecAcl_t *acl = NULL;
268 EXPECT_EQ(OC_STACK_OK, GetDefaultACL(&acl));
269 ASSERT_TRUE(NULL != acl);
271 // Verify if the SRM generated default ACL matches with unit test default
274 OicSecAce_t* tempAce1 = NULL;
275 OicSecAce_t* tempAce2 = NULL;
277 for(tempAce1 = acl->aces, tempAce2 = psAcl->aces;
278 tempAce1 && tempAce2; tempAce1 = tempAce1->next,
279 tempAce2 = tempAce2->next)
281 EXPECT_TRUE(memcmp(tempAce1->subjectuuid.id, tempAce2->subjectuuid.id, sizeof(tempAce1->subjectuuid.id)) == 0);
282 EXPECT_EQ(tempAce1->permission, tempAce2->permission);
283 EXPECT_EQ(GetNumberOfResource(tempAce1), GetNumberOfResource(tempAce2));
287 DeleteACLList(psAcl);
294 TEST(ACLResourceTest, ACLPostTest)
296 // Read an ACL from the file
297 uint8_t *payload = NULL;
300 static OCPersistentStorage ps = OCPersistentStorage();
301 SetPersistentHandler(&ps, true);
303 OicSecAcl_t *defaultAcl = NULL;
304 EXPECT_EQ(OC_STACK_OK, GetDefaultACL(&defaultAcl));
305 ASSERT_TRUE(defaultAcl != NULL);
306 EXPECT_EQ(OC_STACK_OK, SetDefaultACL(defaultAcl));
308 ASSERT_TRUE(ReadCBORFile(ACL1_FILE_NAME, OIC_JSON_ACL_NAME, &payload, &size));
309 ASSERT_TRUE(NULL != payload);
311 OCSecurityPayload *securityPayload = OCSecurityPayloadCreate(payload, size);
312 ASSERT_TRUE(NULL != securityPayload);
314 // Create Entity Handler POST request payload
315 OCEntityHandlerRequest ehReq = OCEntityHandlerRequest();
316 ehReq.method = OC_REST_POST;
317 ehReq.payload = (OCPayload *) securityPayload;
319 ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
321 OicSecAcl_t *acl = CBORPayloadToAcl(payload, size);
322 ASSERT_TRUE(NULL != acl);
324 // Verify if SRM contains ACL for the subject
325 OicSecAce_t *savePtr = NULL;
326 const OicSecAce_t* subjectAcl = GetACLResourceData(&(acl->aces->subjectuuid), &savePtr);
327 ASSERT_TRUE(NULL != subjectAcl);
331 OCPayloadDestroy((OCPayload *) securityPayload);
337 // gAcl is a pointer to the the global ACL used by SRM
338 extern OicSecAcl_t *gAcl;
341 // GetACLResource tests
342 TEST(ACLResourceTest, GetACLResourceTests)
344 // Read an ACL from the file
345 static OCPersistentStorage ps = OCPersistentStorage();
346 SetPersistentHandler(&ps, true);
348 uint8_t *payload = NULL;
351 ASSERT_TRUE(ReadCBORFile(ACL1_FILE_NAME, OIC_JSON_ACL_NAME, &payload, &size));
352 ASSERT_TRUE(payload != NULL);
354 OicSecAcl_t *defaultPsAcl = CBORPayloadToAcl(payload, size);
355 ASSERT_TRUE(defaultPsAcl != NULL);
357 OicSecAcl_t *acl1 = NULL;
358 EXPECT_EQ(OC_STACK_OK, GetDefaultACL(&acl1));
359 ASSERT_TRUE(acl1 != NULL);
360 EXPECT_EQ(OC_STACK_OK, SetDefaultACL(acl1));
362 // Verify that ACL file contains 2 ACE entries for 'WILDCARD' subject
363 const OicSecAce_t *ace = NULL;
364 OicSecAce_t *savePtr = NULL;
365 OicUuid_t subject = WILDCARD_SUBJECT_ID;
370 ace = GetACLResourceData(&subject, &savePtr);
371 count = (NULL != ace) ? count + 1 : count;
372 } while (ace != NULL);
374 EXPECT_EQ(count, NUM_ACE_FOR_WILDCARD_IN_ACL1_DAT);
376 /* Perform cleanup */
378 DeleteACLList(defaultPsAcl);
382 static OCStackResult populateAcl(OicSecAcl_t *acl, int numRsrc)
384 OCStackResult ret = OC_STACK_ERROR;
385 OicSecAce_t* ace = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
386 VERIFY_NON_NULL(TAG, ace, ERROR);
388 memcpy(ace->subjectuuid.id, "2222222222222222", sizeof(ace->subjectuuid.id));
389 EXPECT_EQ(true, AddResourceToACE(ace, "/a/led", "oic.core", "oic.if.r"));
392 EXPECT_EQ(true, AddResourceToACE(ace, "/a/fan", "oic.core", "oic.if.r"));
395 LL_APPEND(acl->aces, ace);
397 memcpy(acl->rownerID.id, "1111111111111111", sizeof(acl->rownerID.id));
408 TEST(ACLResourceTest, ACLDeleteWithSingleResourceTest)
410 static OCPersistentStorage ps = OCPersistentStorage();
411 SetPersistentHandler(&ps, true);
413 OicSecAcl_t *defaultAcl = NULL;
414 EXPECT_EQ(OC_STACK_OK, GetDefaultACL(&defaultAcl));
415 ASSERT_TRUE(defaultAcl != NULL);
416 EXPECT_EQ(OC_STACK_OK, SetDefaultACL(defaultAcl));
419 OicSecAcl_t acl = OicSecAcl_t();
420 EXPECT_EQ(OC_STACK_OK, populateAcl(&acl, 1));
422 //GET CBOR POST payload
424 uint8_t *payload = NULL;
425 EXPECT_EQ(OC_STACK_OK, AclToCBORPayload(&acl, &payload, &size));
426 ASSERT_TRUE(NULL != payload);
429 OCSecurityPayload *securityPayload = OCSecurityPayloadCreate(payload, size);
430 ASSERT_TRUE(NULL != securityPayload);
432 // Create Entity Handler POST request payload
433 OCEntityHandlerRequest ehReq = OCEntityHandlerRequest();
434 ehReq.payload = (OCPayload *) securityPayload;
435 ehReq.method = OC_REST_POST;
436 ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
438 // Verify if SRM contains ACE for the subject
439 OicSecAce_t* savePtr = NULL;
440 const OicSecAce_t* subjectAce1 = GetACLResourceData(&acl.aces->subjectuuid, &savePtr);
441 ASSERT_TRUE(NULL != subjectAce1);
443 // Create Entity Handler DELETE request
444 ehReq.method = OC_REST_DELETE;
445 char query[] = "subjectuuid=32323232-3232-3232-3232-323232323232;resources=/a/led";
446 ehReq.query = (char *)OICMalloc(strlen(query)+1);
447 ASSERT_TRUE(NULL != ehReq.query);
448 OICStrcpy(ehReq.query, strlen(query)+1, query);
449 ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
451 // Verify if SRM has deleted ACE for the subject
453 const OicSecAce_t* subjectAce2 = GetACLResourceData(&acl.aces->subjectuuid, &savePtr);
454 ASSERT_TRUE(NULL == subjectAce2);
458 OICFree(ehReq.query);
459 OCPayloadDestroy((OCPayload *)securityPayload);
463 TEST(ACLResourceTest, ACLDeleteWithMultiResourceTest)
465 static OCPersistentStorage ps = OCPersistentStorage();
466 SetPersistentHandler(&ps, true);
468 OicSecAcl_t *defaultAcl = NULL;
469 EXPECT_EQ(OC_STACK_OK, GetDefaultACL(&defaultAcl));
470 ASSERT_TRUE(defaultAcl != NULL);
471 EXPECT_EQ(OC_STACK_OK, SetDefaultACL(defaultAcl));
474 OicSecAcl_t acl = OicSecAcl_t();
475 EXPECT_EQ(OC_STACK_OK, populateAcl(&acl, 2));
477 //GET CBOR POST payload
479 uint8_t *payload = NULL;
480 EXPECT_EQ(OC_STACK_OK, AclToCBORPayload(&acl, &payload, &size));
481 ASSERT_TRUE(NULL != payload);
484 OCSecurityPayload *securityPayload = OCSecurityPayloadCreate(payload, size);
485 ASSERT_TRUE(NULL!= securityPayload);
487 // Create Entity Handler POST request payload
488 OCEntityHandlerRequest ehReq = OCEntityHandlerRequest();
489 ehReq.method = OC_REST_POST;
490 ehReq.payload = (OCPayload *)securityPayload;
491 ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
493 // Verify if SRM contains ACE for the subject with two resources
494 OicSecAce_t* savePtr = NULL;
495 const OicSecAce_t* subjectAce1 = GetACLResourceData(&acl.aces->subjectuuid, &savePtr);
496 ASSERT_TRUE(NULL != subjectAce1);
497 EXPECT_EQ(2, GetNumberOfResource(subjectAce1));
500 OicSecRsrc_t* rsrc = NULL;
501 LL_FOREACH(subjectAce1->resources, rsrc)
503 printf("%s\n", rsrc->href);
507 // Create Entity Handler DELETE request
508 ehReq.method = OC_REST_DELETE;
509 char query[] = "subjectuuid=32323232-3232-3232-3232-323232323232;resources=/a/led";
510 ehReq.query = (char *)OICMalloc(strlen(query)+1);
511 ASSERT_TRUE(NULL != ehReq.query);
512 OICStrcpy(ehReq.query, strlen(query)+1, query);
514 ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
516 // Verify if SRM contains ACL for the subject but only with one resource
518 const OicSecAce_t* subjectAce2 = GetACLResourceData(&acl.aces->subjectuuid, &savePtr);
519 ASSERT_TRUE(NULL != subjectAce2);
520 EXPECT_EQ(1, GetNumberOfResource(subjectAce2));
523 OCPayloadDestroy((OCPayload *)securityPayload);
525 OICFree(ehReq.query);
529 //'GET' with query ACL test
530 TEST(ACLResourceTest, ACLGetWithQueryTest)
532 static OCPersistentStorage ps = OCPersistentStorage();
533 SetPersistentHandler(&ps, true);
535 OicSecAcl_t *defaultAcl = NULL;
536 EXPECT_EQ(OC_STACK_OK, GetDefaultACL(&defaultAcl));
537 ASSERT_TRUE(defaultAcl != NULL);
538 EXPECT_EQ(OC_STACK_OK, SetDefaultACL(defaultAcl));
541 OicSecAcl_t acl = OicSecAcl_t();
542 EXPECT_EQ(OC_STACK_OK, populateAcl(&acl, 1));
544 //GET CBOR POST payload
546 uint8_t *payload = NULL;
547 EXPECT_EQ(OC_STACK_OK, AclToCBORPayload(&acl, &payload, &size));
548 ASSERT_TRUE(NULL != payload);
551 OCSecurityPayload *securityPayload = OCSecurityPayloadCreate(payload, size);
552 ASSERT_TRUE(NULL != securityPayload);
554 //Create Entity Handler POST request payload
555 OCEntityHandlerRequest ehReq = OCEntityHandlerRequest();
556 ehReq.method = OC_REST_POST;
557 ehReq.payload = (OCPayload *)securityPayload;
558 ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
560 //Create Entity Handler GET request wit query
561 ehReq.method = OC_REST_GET;
562 char query[] = "subjectuuid=32323232-3232-3232-3232-323232323232;resources=/a/led";
563 ehReq.query = (char*)OICMalloc(strlen(query)+1);
564 ASSERT_TRUE(NULL != ehReq.query);
565 OICStrcpy(ehReq.query, strlen(query)+1, query);
567 ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
570 OCPayloadDestroy((OCPayload *)securityPayload);
572 OICFree(ehReq.query);