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>
27 #include "psinterface.h"
28 #include "ocpayload.h"
29 #include "oic_malloc.h"
30 #include "oic_string.h"
31 #include "cainterface.h"
32 #include "secureresourcemanager.h"
33 #include "securevirtualresourcetypes.h"
34 #include "srmresourcestrings.h"
35 #include "aclresource.h"
36 #include "srmtestcommon.h"
37 #include "srmutility.h"
39 #include "doxmresource.h"
40 #include "ocpayload.h"
41 #include "ocpayloadcbor.h"
42 #include "payload_logging.h"
43 #include "security_internals.h"
47 #define TAG "SRM-ACL-UT"
49 // These paths match jenkins build configuration.
50 const char* DEFAULT_ACL_FILE_NAME = "/oic_unittest_default_acl.dat";
51 const char* ACL1_FILE_NAME = "/oic_unittest_acl1.dat";
53 #define NUM_ACE_FOR_WILDCARD_IN_ACL1_DAT (1)
55 TEST(ACLResourceTest, CBORDefaultACLConversion)
57 OicSecAcl_t *defaultAcl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
58 ASSERT_TRUE(defaultAcl != NULL);
59 uint8_t defaultAclSub[] = { 0x2a };
60 memcpy(defaultAcl->subject.id, defaultAclSub, sizeof(defaultAclSub));
61 defaultAcl->permission = 2;
62 const char *defaulAclRsrc[] = { "/oic/res", "/oic/d", "/oic/p", "/oic/res/types/d",
63 "/oic/ad", "/oic/sec/acl", "/oic/sec/doxm", "/oic/sec/pstat"};
64 defaultAcl->resourcesLen = 8;
65 defaultAcl->resources = (char **)OICCalloc(defaultAcl->resourcesLen, sizeof(char *));
66 ASSERT_TRUE(defaultAcl->resources != NULL);
67 for (size_t i = 0 ; i < defaultAcl->resourcesLen; i++)
69 defaultAcl->resources[i] = OICStrdup(defaulAclRsrc[i]);
70 ASSERT_TRUE(defaultAcl->resources[i] != NULL);
72 uint8_t defaultAclOwnrs[] = {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
73 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32};
74 memcpy(defaultAcl->rownerID.id, defaultAclOwnrs, sizeof(defaultAclOwnrs));
76 size_t defaultAclSize = 0;
77 uint8_t *defaultPsStorage = NULL;
78 OCStackResult convRet = AclToCBORPayload(defaultAcl, &defaultPsStorage, &defaultAclSize);
79 EXPECT_EQ(OC_STACK_OK, convRet);
80 ASSERT_TRUE(defaultPsStorage != NULL);
81 EXPECT_NE(0, defaultAclSize);
83 OicSecAcl_t* convertedAcl = CBORPayloadToAcl(defaultPsStorage, defaultAclSize);
84 ASSERT_TRUE(convertedAcl != NULL);
86 EXPECT_EQ(defaultAcl->resourcesLen, convertedAcl->resourcesLen);
87 for(int i = 0; i < convertedAcl->resourcesLen; i++)
89 EXPECT_EQ(0, strcmp(defaultAcl->resources[i], convertedAcl->resources[i]));
92 DeleteACLList(convertedAcl);
93 DeleteACLList(defaultAcl);
94 OICFree(defaultPsStorage);
97 TEST(ACLResourceTest, CBORACLConversion)
99 OicSecAcl_t *secAcl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
100 ASSERT_TRUE(secAcl != NULL);
101 uint8_t subjectBytes[] = { 0x2a };
102 memcpy(secAcl->subject.id, subjectBytes, sizeof(subjectBytes));
103 secAcl->permission = 2;
104 const char *rsrc[] = { "/oic/res", "/oic/d", "/oic/p", "/oic/res/types/d",
105 "/oic/ad", "/oic/sec/acl"};
106 secAcl->resourcesLen = 6;
107 secAcl->resources = (char **)OICCalloc(secAcl->resourcesLen, sizeof(char *));
108 ASSERT_TRUE(secAcl->resources != NULL);
109 for (size_t i = 0 ; i < secAcl->resourcesLen; i++)
111 secAcl->resources[i] = OICStrdup(rsrc[i]);
112 ASSERT_TRUE(secAcl->resources[i] != NULL);
116 uint8_t ownrs[] = {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
117 0x32, 0x32, 0x32, 0x32, 0x32, 0x32};
118 memcpy(secAcl->rownerID.id, ownrs, sizeof(ownrs));
120 OicSecAcl_t *secAcl1 = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
121 ASSERT_TRUE(secAcl1 != NULL);
122 memcpy(secAcl1->subject.id, subjectBytes, sizeof(subjectBytes));
123 secAcl1->permission = 6;
124 const char *rsrc1[] = { "/oic/sec/doxm", "/oic/sec/pstat"};
125 secAcl1->resourcesLen = 2;
126 secAcl1->resources = (char **)OICCalloc(secAcl1->resourcesLen, sizeof(char *));
127 ASSERT_TRUE(secAcl1->resources != NULL);
128 for (size_t i = 0 ; i < secAcl1->resourcesLen; i++)
130 secAcl1->resources[i] = OICStrdup(rsrc1[i]);
131 ASSERT_TRUE(secAcl1->resources[i] != NULL);
133 memcpy(secAcl1->rownerID.id, ownrs, sizeof(ownrs));
134 secAcl->next = secAcl1;
136 OicSecAcl_t *secAcl2 = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
137 ASSERT_TRUE(secAcl2 != NULL);
138 uint8_t subjectBytes1[] = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
139 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
140 memcpy(secAcl2->subject.id, subjectBytes1, sizeof(subjectBytes1));
141 secAcl2->permission = 255;
142 const char *rsrc2[] = {"/oic/light", "/oic/fan" };
143 secAcl2->resourcesLen = 2;
144 secAcl2->resources = (char **)OICCalloc(secAcl2->resourcesLen, sizeof(char *));
145 ASSERT_TRUE(secAcl2->resources != NULL);
146 for (size_t i = 0 ; i < secAcl2->resourcesLen; i++)
148 secAcl2->resources[i] = OICStrdup(rsrc2[i]);
149 ASSERT_TRUE(secAcl2->resources[i] != NULL);
151 memcpy(secAcl2->rownerID.id, ownrs, sizeof(ownrs));
152 secAcl1->next = secAcl2;
154 OicSecAcl_t *secAcl3 = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
155 ASSERT_TRUE(secAcl3 != NULL);
156 uint8_t subjectBytes2[] = {0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
157 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33};
158 memcpy(secAcl3->subject.id, subjectBytes2, sizeof(subjectBytes2));
159 secAcl3->permission = 255;
160 const char *rsrc3[] = {"/oic/light", "/oic/garage" };
161 secAcl3->resourcesLen = 2;
162 secAcl3->resources = (char **)OICCalloc(secAcl3->resourcesLen, sizeof(char *));
163 ASSERT_TRUE(secAcl3->resources != NULL);
164 for (size_t i = 0 ; i < secAcl3->resourcesLen; i++)
166 secAcl3->resources[i] = OICStrdup(rsrc3[i]);
167 ASSERT_TRUE(secAcl3->resources[i] != NULL);
169 memcpy(secAcl3->rownerID.id, ownrs, sizeof(ownrs));
170 secAcl2->next = secAcl3;
171 secAcl3->next = NULL;
174 uint8_t *psStorage = NULL;
175 EXPECT_EQ(OC_STACK_OK, AclToCBORPayload(secAcl, &psStorage, &size));
176 ASSERT_TRUE(NULL != psStorage);
177 OicSecAcl_t *acl = CBORPayloadToAcl(psStorage, size);
178 ASSERT_TRUE(NULL != acl);
179 EXPECT_EQ(2, acl->permission);
180 EXPECT_EQ(6 , acl->resourcesLen);
181 EXPECT_STREQ("/oic/res", acl->resources[0]);
184 DeleteACLList(secAcl);
188 TEST(ACLResourceTest, InitAclResource)
190 EXPECT_EQ(OC_STACK_INVALID_PARAM, InitACLResource());
191 EXPECT_EQ(OC_STACK_INVALID_PARAM, DeInitACLResource());
195 TEST(ACLResourceTest, GetDefaultACLTests)
197 uint8_t *payload = NULL;
200 ASSERT_TRUE(ReadCBORFile(DEFAULT_ACL_FILE_NAME, OIC_JSON_ACL_NAME, &payload, &size));
201 ASSERT_TRUE(payload != NULL);
203 OicSecAcl_t *psAcl = CBORPayloadToAcl(payload, size);
204 ASSERT_TRUE(psAcl != NULL);
206 OicSecAcl_t *acl = NULL;
207 EXPECT_EQ(OC_STACK_OK, GetDefaultACL(&acl));
208 ASSERT_TRUE(acl != NULL);
210 // Verify if the SRM generated default ACL matches with unit test default
213 EXPECT_TRUE(strcmp((char*)acl->subject.id, (char*)psAcl->subject.id) == 0);
214 EXPECT_EQ(acl->resourcesLen, psAcl->resourcesLen);
215 for (size_t i = 0; i < acl->resourcesLen; i++)
217 EXPECT_EQ(strlen(acl->resources[i]), strlen(psAcl->resources[i]));
218 EXPECT_TRUE(memcmp(acl->resources[i], psAcl->resources[i],
219 strlen(acl->resources[i])) == 0);
221 EXPECT_EQ(acl->permission, psAcl->permission);
224 DeleteACLList(psAcl);
231 TEST(ACLResourceTest, ACLPostTest)
233 // Read an ACL from the file
234 uint8_t *payload = NULL;
237 ASSERT_TRUE(ReadCBORFile(ACL1_FILE_NAME, OIC_JSON_ACL_NAME, &payload, &size));
238 ASSERT_TRUE(NULL != payload);
240 OCSecurityPayload *securityPayload = OCSecurityPayloadCreate(payload, size);
241 ASSERT_TRUE(NULL != securityPayload);
243 static OCPersistentStorage ps = OCPersistentStorage();
244 SetPersistentHandler(&ps, true);
246 // Create Entity Handler POST request payload
247 OCEntityHandlerRequest ehReq = OCEntityHandlerRequest();
248 ehReq.method = OC_REST_POST;
249 ehReq.payload = (OCPayload *) securityPayload;
251 ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
253 OicSecAcl_t *acl = CBORPayloadToAcl(payload, size);
254 ASSERT_TRUE(NULL != acl);
256 // Verify if SRM contains ACL for the subject
257 OicSecAcl_t *savePtr = NULL;
258 const OicSecAcl_t* subjectAcl = GetACLResourceData(&(acl->subject), &savePtr);
259 ASSERT_TRUE(NULL != subjectAcl);
263 OCPayloadDestroy((OCPayload *) securityPayload);
268 // GetACLResource tests
269 TEST(ACLResourceTest, GetACLResourceTests)
271 // Read an ACL from the file
272 static OCPersistentStorage ps = OCPersistentStorage();
273 SetPersistentHandler(&ps, true);
275 uint8_t *payload = NULL;
278 ASSERT_TRUE(ReadCBORFile(ACL1_FILE_NAME, OIC_JSON_ACL_NAME, &payload, &size));
279 ASSERT_TRUE(payload != NULL);
281 OicSecAcl_t *defaultPsAcl = CBORPayloadToAcl(payload, size);
282 ASSERT_TRUE(defaultPsAcl != NULL);
284 OicSecAcl_t *acl1 = NULL;
285 EXPECT_EQ(OC_STACK_OK, GetDefaultACL(&acl1));
286 ASSERT_TRUE(acl1 != NULL);
287 EXPECT_EQ(OC_STACK_OK, SetDefaultACL(acl1));
289 // Verify that ACL file contains 2 ACE entries for 'WILDCARD' subject
290 const OicSecAcl_t *acl = NULL;
291 OicSecAcl_t *savePtr = NULL;
292 OicUuid_t subject = WILDCARD_SUBJECT_ID;
297 acl = GetACLResourceData(&subject, &savePtr);
298 count = (NULL != acl) ? count + 1 : count;
299 } while (acl != NULL);
301 EXPECT_EQ(count, NUM_ACE_FOR_WILDCARD_IN_ACL1_DAT);
303 /* Perform cleanup */
305 DeleteACLList(defaultPsAcl);
309 static OCStackResult populateAcl(OicSecAcl_t *acl, int numRsrc)
311 OCStackResult ret = OC_STACK_ERROR;
312 memcpy(acl->subject.id, "2222222222222222", sizeof(acl->subject.id));
313 acl->resourcesLen = (size_t)numRsrc;
314 acl->resources = (char**)OICCalloc(acl->resourcesLen, sizeof(char*));
315 VERIFY_NON_NULL(TAG, acl->resources, ERROR);
316 acl->resources[0] = (char*)OICMalloc(strlen("/a/led")+1);
317 VERIFY_NON_NULL(TAG, acl->resources[0], ERROR);
318 OICStrcpy(acl->resources[0], strlen("/a/led")+1, "/a/led");
321 acl->resources[1] = (char*)OICMalloc(strlen("/a/fan")+1);
322 VERIFY_NON_NULL(TAG, acl->resources[1], ERROR);
323 OICStrcpy(acl->resources[1], strlen("/a/fan")+1, "/a/fan");
326 memcpy(acl->rownerID.id, "1111111111111111", sizeof(acl->rownerID.id));
335 TEST(ACLResourceTest, ACLDeleteWithSingleResourceTest)
338 OicSecAcl_t acl = OicSecAcl_t();
339 EXPECT_EQ(OC_STACK_OK, populateAcl(&acl, 1));
341 //GET CBOR POST payload
343 uint8_t *payload = NULL;
344 EXPECT_EQ(OC_STACK_OK, AclToCBORPayload(&acl, &payload, &size));
345 ASSERT_TRUE(NULL != payload);
348 OCSecurityPayload *securityPayload = OCSecurityPayloadCreate(payload, size);
349 ASSERT_TRUE(NULL != securityPayload);
351 static OCPersistentStorage ps = OCPersistentStorage();
352 SetPersistentHandler(&ps, true);
354 // Create Entity Handler POST request payload
355 OCEntityHandlerRequest ehReq = OCEntityHandlerRequest();
356 ehReq.payload = (OCPayload *) securityPayload;
357 ehReq.method = OC_REST_POST;
358 ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
360 // Verify if SRM contains ACE for the subject
361 OicSecAcl_t* savePtr = NULL;
362 const OicSecAcl_t* subjectAcl1 = GetACLResourceData(&acl.subject, &savePtr);
363 ASSERT_TRUE(NULL != subjectAcl1);
365 // Create Entity Handler DELETE request
366 ehReq.method = OC_REST_DELETE;
367 char query[] = "subjectuuid=2222222222222222;resources=/a/led";
368 ehReq.query = (char *)OICMalloc(strlen(query)+1);
369 ASSERT_TRUE(NULL != ehReq.query);
370 OICStrcpy(ehReq.query, strlen(query)+1, query);
371 ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
373 // Verify if SRM has deleted ACE for the subject
375 const OicSecAcl_t* subjectAcl2 = GetACLResourceData(&acl.subject, &savePtr);
376 ASSERT_TRUE(NULL == subjectAcl2);
380 OICFree(ehReq.query);
381 OCPayloadDestroy((OCPayload *)securityPayload);
385 TEST(ACLResourceTest, ACLDeleteWithMultiResourceTest)
388 OicSecAcl_t acl = OicSecAcl_t();
389 EXPECT_EQ(OC_STACK_OK, populateAcl(&acl, 2));
391 //GET CBOR POST payload
393 uint8_t *payload = NULL;
394 EXPECT_EQ(OC_STACK_OK, AclToCBORPayload(&acl, &payload, &size));
395 ASSERT_TRUE(NULL != payload);
398 OCSecurityPayload *securityPayload = OCSecurityPayloadCreate(payload, size);
399 ASSERT_TRUE(NULL!= securityPayload);
401 static OCPersistentStorage ps = OCPersistentStorage();
402 SetPersistentHandler(&ps, true);
404 // Create Entity Handler POST request payload
405 OCEntityHandlerRequest ehReq = OCEntityHandlerRequest();
406 ehReq.method = OC_REST_POST;
407 ehReq.payload = (OCPayload *)securityPayload;
408 ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
410 // Verify if SRM contains ACE for the subject with two resources
411 OicSecAcl_t* savePtr = NULL;
412 const OicSecAcl_t* subjectAcl1 = GetACLResourceData(&acl.subject, &savePtr);
413 ASSERT_TRUE(NULL != subjectAcl1);
414 EXPECT_EQ(2, subjectAcl1->resourcesLen);
416 // Create Entity Handler DELETE request
417 ehReq.method = OC_REST_DELETE;
418 char query[] = "subjectuuid=2222222222222222;resources=/a/led";
419 ehReq.query = (char *)OICMalloc(strlen(query)+1);
420 ASSERT_TRUE(NULL != ehReq.query);
421 OICStrcpy(ehReq.query, strlen(query)+1, query);
423 ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
425 // Verify if SRM contains ACL for the subject but only with one resource
427 const OicSecAcl_t* subjectAcl2 = GetACLResourceData(&acl.subject, &savePtr);
428 ASSERT_TRUE(NULL != subjectAcl2);
429 EXPECT_EQ(1, subjectAcl2->resourcesLen);
432 OCPayloadDestroy((OCPayload *)securityPayload);
434 OICFree(ehReq.query);
438 //'GET' with query ACL test
439 TEST(ACLResourceTest, ACLGetWithQueryTest)
442 OicSecAcl_t acl = OicSecAcl_t();
443 EXPECT_EQ(OC_STACK_OK, populateAcl(&acl, 1));
445 //GET CBOR POST payload
447 uint8_t *payload = NULL;
448 EXPECT_EQ(OC_STACK_OK, AclToCBORPayload(&acl, &payload, &size));
449 ASSERT_TRUE(NULL != payload);
452 OCSecurityPayload *securityPayload = OCSecurityPayloadCreate(payload, size);
453 ASSERT_TRUE(NULL != securityPayload);
455 static OCPersistentStorage ps = OCPersistentStorage();
456 SetPersistentHandler(&ps, true);
458 //Create Entity Handler POST request payload
459 OCEntityHandlerRequest ehReq = OCEntityHandlerRequest();
460 ehReq.method = OC_REST_POST;
461 ehReq.payload = (OCPayload *)securityPayload;
462 ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
464 //Create Entity Handler GET request wit query
465 ehReq.method = OC_REST_GET;
466 char query[] = "subjectuuid=2222222222222222;resources=/a/led";
467 ehReq.query = (char*)OICMalloc(strlen(query)+1);
468 ASSERT_TRUE(NULL != ehReq.query);
469 OICStrcpy(ehReq.query, strlen(query)+1, query);
471 ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
474 OCPayloadDestroy((OCPayload *)securityPayload);
476 OICFree(ehReq.query);