Skip to content

Commit d494d2d

Browse files
committed
[attestation-service] Fix Bug In End-To-End SGX Tests
1 parent 9729eaf commit d494d2d

File tree

16 files changed

+418
-44
lines changed

16 files changed

+418
-44
lines changed

GEMINI.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,3 +120,25 @@ the sysroot container. To do so, you may use `accli` as follows:
120120
# To build/test applications.
121121
./scripts/accli_wrapper.sh applications {build,test}
122122
```
123+
124+
For C++ code, only add block comments in header files (if present) and use
125+
doxygen-style documentation, e.g:
126+
127+
```
128+
/**
129+
* @brief Packs a FullKey from a vector of authorities and base64-encoded
130+
* partial keys.
131+
*
132+
* This is an overload of packFullKey that accepts partial keys as
133+
* base64-encoded strings. It decodes the keys and then calls the primary
134+
* packFullKey function, finally returning a base64-encoded string of the packed
135+
* key.
136+
*
137+
* @param authorities A const reference to a vector of authority strings.
138+
* @param partial_keys_b64 A const reference to a vector of base64-encoded
139+
* partial key strings.
140+
* @return A std::string containing the base64-encoded serialized FullKey.
141+
*/
142+
std::string packFullKey(const std::vector<std::string> &authorities,
143+
const std::vector<std::string> &partial_keys_b64);
144+
```

accless/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
To build:
44

55
```bash
6-
accli docker run --mount --cwd /code/accless/accless python3 build.py [-- --clean]
6+
accli accless build
77
```
88

99
To test:
1010

1111
```bash
12-
accli docker run --mount --cwd /code/accless/accless/build-native ctest -- --output-on-failure
12+
accli accless test
1313
```

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

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,23 @@ SetupOutput setup(const std::vector<std::string> &auths) {
2525
return {result_json["msk"], result_json["mpk"]};
2626
}
2727

28+
SetupOutput setupPartial(const std::string &auth_id) {
29+
char *result = setup_partial_abe4(auth_id.c_str());
30+
if (!result) {
31+
std::cerr
32+
<< "accless(abe4): FFI call to setup_partial_abe4 failed. See Rust "
33+
"logs for details."
34+
<< std::endl;
35+
throw std::runtime_error(
36+
"accless(abe4): setup_partial_abe4 FFI call failed");
37+
}
38+
39+
auto result_json = nlohmann::json::parse(result);
40+
free_string(result);
41+
42+
return {result_json["msk"], result_json["mpk"]};
43+
}
44+
2845
std::string keygen(const std::string &gid, const std::string &msk,
2946
const std::vector<UserAttribute> &user_attrs) {
3047
nlohmann::json user_attrs_json = nlohmann::json::array();
@@ -49,6 +66,33 @@ std::string keygen(const std::string &gid, const std::string &msk,
4966
return usk_b64;
5067
}
5168

69+
std::string keygenPartial(const std::string &gid,
70+
const std::string &partial_msk_b64,
71+
const std::vector<UserAttribute> &user_attrs) {
72+
nlohmann::json user_attrs_json = nlohmann::json::array();
73+
for (const auto &attr : user_attrs) {
74+
user_attrs_json.push_back({{"authority", attr.authority},
75+
{"label", attr.label},
76+
{"attribute", attr.attribute}});
77+
}
78+
79+
char *result = keygen_partial_abe4(gid.c_str(), partial_msk_b64.c_str(),
80+
user_attrs_json.dump().c_str());
81+
if (!result) {
82+
std::cerr << "accless(abe4): FFI call to keygen_partial_abe4 failed. "
83+
"See Rust "
84+
"logs for details."
85+
<< std::endl;
86+
throw std::runtime_error(
87+
"accless(abe4): keygen_partial_abe4 FFI call failed");
88+
}
89+
90+
std::string partial_usk_b64(result);
91+
free_string(result);
92+
93+
return partial_usk_b64;
94+
}
95+
5296
EncryptOutput encrypt(const std::string &mpk, const std::string &policy) {
5397
char *result = encrypt_abe4(mpk.c_str(), policy.c_str());
5498
if (!result) {
@@ -136,11 +180,12 @@ packFullKey(const std::vector<std::string> &authorities,
136180
pair.first.end());
137181

138182
uint64_t key_len = pair.second.size();
139-
full_key_bytes.insert(
140-
full_key_bytes.end(), reinterpret_cast<const uint8_t *>(&key_len),
141-
reinterpret_cast<const uint8_t *>(&key_len) + sizeof(uint64_t));
183+
full_key_bytes.insert(full_key_bytes.end(),
184+
reinterpret_cast<const uint8_t *>(&key_len),
185+
reinterpret_cast<const uint8_t *>(&key_len) +
186+
sizeof(uint64_t)); // 4. Partial key length
142187
full_key_bytes.insert(full_key_bytes.end(), pair.second.begin(),
143-
pair.second.end());
188+
pair.second.end()); // 5. Partial key bytes
144189
}
145190

146191
return full_key_bytes;

accless/libs/abe4/cpp-bindings/abe4.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ char *keygen_abe4(const char *gid, const char *msk_b64,
1414
char *encrypt_abe4(const char *mpk_b64, const char *policy_str);
1515
char *decrypt_abe4(const char *usk_b64, const char *gid, const char *policy_str,
1616
const char *ct_b64);
17+
char *setup_partial_abe4(const char *auth_id_cstr);
18+
char *keygen_partial_abe4(const char *gid_cstr,
19+
const char *partial_msk_b64_cstr,
20+
const char *user_attrs_json);
1721

1822
} // extern "C"
1923

@@ -36,6 +40,22 @@ struct UserAttribute {
3640

3741
SetupOutput setup(const std::vector<std::string> &auths);
3842

43+
/**
44+
* @brief Generates a partial Master Secret Key (MSK) and a partial Master
45+
* Public Key (MPK) for a single authority.
46+
*
47+
* This function acts as a C++ wrapper around the Rust `setup_partial` FFI
48+
* function. It takes an authority ID, calls the Rust FFI function, parses the
49+
* JSON output, and returns a `SetupOutput` struct containing the base64-encoded
50+
* partial MSK and MPK.
51+
*
52+
* @param auth_id The unique identifier of the authority.
53+
* @return A `SetupOutput` struct containing the base64-encoded partial MSK and
54+
* MPK.
55+
* @throws std::runtime_error on error.
56+
*/
57+
SetupOutput setupPartial(const std::string &auth_id);
58+
3959
/**
4060
* @brief Generates a User Secret Key (USK) for a given global ID, Master Secret
4161
* Key (MSK), and a set of user attributes.
@@ -54,6 +74,28 @@ SetupOutput setup(const std::vector<std::string> &auths);
5474
std::string keygen(const std::string &gid, const std::string &msk,
5575
const std::vector<UserAttribute> &user_attrs);
5676

77+
/**
78+
* @brief Generates a partial User Secret Key (USK) for a given global ID,
79+
* partial Master Secret Key (MSK), and a set of user attributes.
80+
*
81+
* This function acts as a C++ wrapper around the Rust `keygen_partial` FFI
82+
* function. It takes the group ID, a base64 encoded partial Master Secret Key,
83+
* and a vector of UserAttribute objects. It serializes the user attributes to
84+
* JSON, calls the Rust FFI function, and returns the base64 encoded partial
85+
* User Secret Key.
86+
*
87+
* @param gid The group ID for which the partial USK is to be generated.
88+
* @param partial_msk_b64 A base64 encoded string representing the partial
89+
* Master Secret Key.
90+
* @param user_attrs A vector of UserAttribute objects associated with the user.
91+
* @return A base64 encoded string representing the generated partial User
92+
* Secret Key (USK).
93+
* @throws std::runtime_error on error.
94+
*/
95+
std::string keygenPartial(const std::string &gid,
96+
const std::string &partial_msk_b64,
97+
const std::vector<UserAttribute> &user_attrs);
98+
5799
/**
58100
* @brief Encrypts a message using the Master Public Key (MPK) and a policy.
59101
*

accless/libs/abe4/cpp-bindings/tests.cpp

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -121,33 +121,47 @@ TEST(Abe4Test, PackFullKey) {
121121
EXPECT_EQ(packed_mpk_b64, setup_output.mpk);
122122
}
123123

124-
TEST(Abe4Test, EndToEndSingleAuthority) {
125-
std::string auth = "auth1";
126-
accless::abe4::SetupOutput setup_output = accless::abe4::setup({auth});
127-
ASSERT_FALSE(setup_output.msk.empty());
128-
ASSERT_FALSE(setup_output.mpk.empty());
129-
124+
TEST(Abe4Test, EndToEndSingleAuthorityPartial) {
125+
std::string auth_id = "TEST_AUTH_ID";
130126
std::string gid = "test_gid";
131127
std::string wfId = "foo";
132128
std::string nodeId = "bar";
133129

130+
// 1. Setup partial keys
131+
accless::abe4::SetupOutput partial_setup_output =
132+
accless::abe4::setupPartial(auth_id);
133+
ASSERT_FALSE(partial_setup_output.msk.empty());
134+
ASSERT_FALSE(partial_setup_output.mpk.empty());
135+
136+
// 2. Keygen partial USK
137+
std::vector<accless::abe4::UserAttribute> user_attrs = {
138+
{auth_id, "wf", wfId}, {auth_id, "node", nodeId}};
139+
std::string partial_usk_b64 =
140+
accless::abe4::keygenPartial(gid, partial_setup_output.msk, user_attrs);
141+
ASSERT_FALSE(partial_usk_b64.empty());
142+
143+
// 3. Pack full MPK
144+
std::string mpk =
145+
accless::abe4::packFullKey({auth_id}, {partial_setup_output.mpk});
146+
ASSERT_FALSE(mpk.empty());
147+
148+
// 4. Pack full USK
149+
std::string usk = accless::abe4::packFullKey({auth_id}, {partial_usk_b64});
150+
ASSERT_FALSE(usk.empty());
151+
152+
// 5. Define policy
134153
std::string policy =
135-
auth + ".wf:" + wfId + " & " + auth + ".node:" + nodeId;
154+
auth_id + ".wf:" + wfId + " & " + auth_id + ".node:" + nodeId;
136155

156+
// 6. Encrypt
137157
accless::abe4::EncryptOutput encrypt_output =
138-
accless::abe4::encrypt(setup_output.mpk, policy);
158+
accless::abe4::encrypt(mpk, policy);
139159
ASSERT_FALSE(encrypt_output.gt.empty());
140160
ASSERT_FALSE(encrypt_output.ciphertext.empty());
141161

142-
std::vector<accless::abe4::UserAttribute> user_attrs = {
143-
{auth, "wf", wfId}, {auth, "node", nodeId}};
144-
145-
std::string usk_b64 =
146-
accless::abe4::keygen(gid, setup_output.msk, user_attrs);
147-
ASSERT_FALSE(usk_b64.empty());
148-
162+
// 7. Decrypt
149163
std::optional<std::string> decrypted_gt =
150-
accless::abe4::decrypt(usk_b64, gid, policy, encrypt_output.ciphertext);
164+
accless::abe4::decrypt(usk, gid, policy, encrypt_output.ciphertext);
151165
ASSERT_TRUE(decrypted_gt.has_value());
152166
EXPECT_EQ(decrypted_gt.value(), encrypt_output.gt);
153167
}

0 commit comments

Comments
 (0)