Skip to content

Commit 2f05536

Browse files
committed
[accless] Add API Tests For The C++ FFI Library
1 parent 6291941 commit 2f05536

File tree

2 files changed

+223
-0
lines changed

2 files changed

+223
-0
lines changed

accless/libs/abe4/cpp-bindings/CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,15 @@ if (NOT CMAKE_SYSTEM_NAME STREQUAL "WASI")
6868

6969
include(GoogleTest)
7070
gtest_discover_tests(${TESTS_TARGET} TEST_PREFIX abe4::)
71+
72+
set(API_TESTS_TARGET abe_cpp_api_tests)
73+
add_executable(${API_TESTS_TARGET} api_tests.cpp)
74+
target_link_libraries(${API_TESTS_TARGET} PRIVATE
75+
GTest::gtest_main
76+
accless::abe4
77+
)
78+
target_compile_options(${API_TESTS_TARGET} PRIVATE -Wno-deprecated-declarations)
79+
80+
include(GoogleTest)
81+
gtest_discover_tests(${API_TESTS_TARGET} TEST_PREFIX abe4::)
7182
endif ()
Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
#include "abe4.h"
2+
#include "base64.h"
3+
#include <gtest/gtest.h>
4+
#include <regex>
5+
#include <set>
6+
7+
class Abe4ApiTest : public ::testing::Test {
8+
protected:
9+
void assert_decryption_ok(
10+
const std::vector<accless::abe4::UserAttribute> &user_attrs,
11+
const std::string &policy) {
12+
std::vector<std::string> auths;
13+
std::set<std::string> auth_set;
14+
15+
for (const auto &attr : user_attrs) {
16+
auth_set.insert(attr.authority);
17+
}
18+
19+
std::regex re("([A-Z])\\.");
20+
std::sregex_iterator it(policy.begin(), policy.end(), re);
21+
std::sregex_iterator end;
22+
23+
for (; it != end; ++it) {
24+
auth_set.insert((*it)[1]);
25+
}
26+
27+
for (const auto &auth : auth_set) {
28+
auths.push_back(auth);
29+
}
30+
if (auths.empty()) {
31+
auths.push_back("A");
32+
}
33+
34+
accless::abe4::SetupOutput setup_output = accless::abe4::setup(auths);
35+
std::string gid = "test_gid";
36+
std::string usk_b64 =
37+
accless::abe4::keygen(gid, setup_output.msk, user_attrs);
38+
accless::abe4::EncryptOutput encrypt_output =
39+
accless::abe4::encrypt(setup_output.mpk, policy);
40+
std::optional<std::string> decrypted_gt = accless::abe4::decrypt(
41+
usk_b64, gid, policy, encrypt_output.ciphertext);
42+
43+
ASSERT_TRUE(decrypted_gt.has_value());
44+
EXPECT_EQ(decrypted_gt.value(), encrypt_output.gt);
45+
}
46+
47+
void assert_decryption_fail(
48+
const std::vector<accless::abe4::UserAttribute> &user_attrs,
49+
const std::string &policy) {
50+
std::vector<std::string> auths;
51+
std::set<std::string> auth_set;
52+
53+
for (const auto &attr : user_attrs) {
54+
auth_set.insert(attr.authority);
55+
}
56+
57+
std::regex re("([A-Z])\\.");
58+
std::sregex_iterator it(policy.begin(), policy.end(), re);
59+
std::sregex_iterator end;
60+
61+
for (; it != end; ++it) {
62+
auth_set.insert((*it)[1]);
63+
}
64+
65+
for (const auto &auth : auth_set) {
66+
auths.push_back(auth);
67+
}
68+
if (auths.empty()) {
69+
auths.push_back("A");
70+
}
71+
72+
accless::abe4::SetupOutput setup_output = accless::abe4::setup(auths);
73+
std::string gid = "test_gid";
74+
std::string usk_b64 =
75+
accless::abe4::keygen(gid, setup_output.msk, user_attrs);
76+
accless::abe4::EncryptOutput encrypt_output =
77+
accless::abe4::encrypt(setup_output.mpk, policy);
78+
std::optional<std::string> decrypted_gt = accless::abe4::decrypt(
79+
usk_b64, gid, policy, encrypt_output.ciphertext);
80+
81+
ASSERT_FALSE(decrypted_gt.has_value());
82+
}
83+
};
84+
85+
TEST_F(Abe4ApiTest, SingleAuthSingleOk) {
86+
std::vector<accless::abe4::UserAttribute> user_attrs = {{"A", "a", "0"}};
87+
std::string policy = "A.a:0";
88+
assert_decryption_ok(user_attrs, policy);
89+
}
90+
91+
TEST_F(Abe4ApiTest, SingleAuthSingleFail) {
92+
std::vector<accless::abe4::UserAttribute> user_attrs = {};
93+
std::string policy = "A.a:0";
94+
assert_decryption_fail(user_attrs, policy);
95+
}
96+
97+
TEST_F(Abe4ApiTest, SingleAuthConjunctionOk) {
98+
99+
std::vector<accless::abe4::UserAttribute> user_attrs = {{"A", "a", "0"},
100+
{"A", "b", "0"}};
101+
102+
std::string policy = "A.a:0 & A.b:0";
103+
104+
assert_decryption_ok(user_attrs, policy);
105+
}
106+
107+
TEST_F(Abe4ApiTest, SingleAuthConjunctionFail) {
108+
109+
std::vector<accless::abe4::UserAttribute> user_attrs = {{"A", "a", "0"}};
110+
111+
std::string policy = "A.a:0 & A.b:0";
112+
113+
assert_decryption_fail(user_attrs, policy);
114+
}
115+
116+
TEST_F(Abe4ApiTest, SingleAuthDisjunctionOk) {
117+
118+
std::vector<accless::abe4::UserAttribute> user_attrs = {{"A", "a", "0"}};
119+
120+
std::string policy = "A.a:0 | A.a:1";
121+
122+
assert_decryption_ok(user_attrs, policy);
123+
}
124+
125+
TEST_F(Abe4ApiTest, SingleAuthDisjunctionFail) {
126+
127+
std::vector<accless::abe4::UserAttribute> user_attrs = {};
128+
129+
std::string policy = "A.a:0 | A.b:0";
130+
131+
assert_decryption_fail(user_attrs, policy);
132+
}
133+
134+
TEST_F(Abe4ApiTest, MultiAuthDisjunctionOk) {
135+
136+
std::vector<accless::abe4::UserAttribute> user_attrs = {{"A", "a", "0"}};
137+
138+
std::string policy = "A.a:0 | B.a:0";
139+
140+
assert_decryption_ok(user_attrs, policy);
141+
}
142+
143+
TEST_F(Abe4ApiTest, MultiAuthDisjunctionFail) {
144+
145+
std::vector<accless::abe4::UserAttribute> user_attrs = {{"C", "a", "0"}};
146+
147+
std::string policy = "A.a:0 | B.a:0";
148+
149+
assert_decryption_fail(user_attrs, policy);
150+
}
151+
152+
TEST_F(Abe4ApiTest, MultiAuthConjunctionOk) {
153+
154+
std::vector<accless::abe4::UserAttribute> user_attrs = {{"A", "a", "0"},
155+
{"B", "a", "0"}};
156+
157+
std::string policy = "A.a:0 & B.a:0";
158+
159+
assert_decryption_ok(user_attrs, policy);
160+
}
161+
162+
TEST_F(Abe4ApiTest, MultiAuthConjunctionFail) {
163+
164+
std::vector<accless::abe4::UserAttribute> user_attrs = {{"A", "a", "0"}};
165+
166+
std::string policy = "A.a:0 & B.a:0";
167+
168+
assert_decryption_fail(user_attrs, policy);
169+
}
170+
171+
TEST_F(Abe4ApiTest, SingleAuthComplex1Ok) {
172+
173+
std::vector<accless::abe4::UserAttribute> user_attrs = {{"A", "a", "0"},
174+
{"A", "c", "0"}};
175+
176+
std::string policy = "A.a:0 | (A.b:0 & A.a:2) & (A.c:0 | A.c:1)";
177+
178+
assert_decryption_ok(user_attrs, policy);
179+
}
180+
181+
TEST_F(Abe4ApiTest, SingleAuthComplex1Fail) {
182+
183+
std::vector<accless::abe4::UserAttribute> user_attrs = {{"A", "a", "2"},
184+
{"A", "c", "2"}};
185+
186+
std::string policy = "A.a:0 | (A.b:0 & A.a:2) & (A.c:0 | A.c:1)";
187+
188+
assert_decryption_fail(user_attrs, policy);
189+
}
190+
191+
TEST_F(Abe4ApiTest, MultiAuthComplex1Ok) {
192+
193+
std::vector<accless::abe4::UserAttribute> user_attrs = {{"A", "a", "0"},
194+
{"A", "b", "2"},
195+
{"A", "c", "1"},
196+
{"B", "b", "0"},
197+
{"B", "b", "1"}};
198+
199+
std::string policy = "A.a:1 | (!A.a:1 & A.b:2) & !(B.b:2 | A.c:2)";
200+
201+
assert_decryption_ok(user_attrs, policy);
202+
}
203+
204+
TEST_F(Abe4ApiTest, MultiAuthComplex1Fail) {
205+
206+
std::vector<accless::abe4::UserAttribute> user_attrs = {
207+
{"A", "a", "2"}, {"A", "c", "1"}, {"B", "c", "2"}};
208+
209+
std::string policy = "A.a:0 | (A.b:0 & A.a:2) & (A.c:1 | A.c:2)";
210+
211+
assert_decryption_fail(user_attrs, policy);
212+
}

0 commit comments

Comments
 (0)