Added identity-domain validation and duplicate EdgeRef handling to the FS adapter, plus new FS tests
This commit is contained in:
parent
070265085f
commit
47504644f7
|
|
@ -6,6 +6,56 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static bool amduat_tgk_store_fs_id_space_valid(
|
||||
amduat_tgk_id_space_config_t id_space) {
|
||||
size_t i;
|
||||
size_t j;
|
||||
|
||||
if (id_space.domains_len != 0 && id_space.domains == NULL) {
|
||||
return false;
|
||||
}
|
||||
for (i = 0; i < id_space.domains_len; ++i) {
|
||||
for (j = i + 1; j < id_space.domains_len; ++j) {
|
||||
if (id_space.domains[i].hash_id == id_space.domains[j].hash_id) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool amduat_tgk_store_fs_artifact_eq(amduat_artifact_t a,
|
||||
amduat_artifact_t b) {
|
||||
if ((a.bytes.len != 0 && a.bytes.data == NULL) ||
|
||||
(b.bytes.len != 0 && b.bytes.data == NULL)) {
|
||||
return false;
|
||||
}
|
||||
return amduat_artifact_eq(a, b);
|
||||
}
|
||||
|
||||
static bool amduat_tgk_store_fs_reference_clone(amduat_reference_t src,
|
||||
amduat_reference_t *dst) {
|
||||
uint8_t *digest_copy;
|
||||
|
||||
if (dst == NULL) {
|
||||
return false;
|
||||
}
|
||||
*dst = amduat_reference(src.hash_id, amduat_octets(NULL, 0));
|
||||
if (src.digest.len == 0) {
|
||||
return true;
|
||||
}
|
||||
if (src.digest.data == NULL) {
|
||||
return false;
|
||||
}
|
||||
digest_copy = (uint8_t *)malloc(src.digest.len);
|
||||
if (digest_copy == NULL) {
|
||||
return false;
|
||||
}
|
||||
memcpy(digest_copy, src.digest.data, src.digest.len);
|
||||
dst->digest = amduat_octets(digest_copy, src.digest.len);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void amduat_tgk_store_fs_reference_free(amduat_reference_t *ref) {
|
||||
if (ref == NULL) {
|
||||
return;
|
||||
|
|
@ -166,6 +216,7 @@ bool amduat_tgk_store_fs_init(amduat_tgk_store_fs_t *fs,
|
|||
amduat_reference_t *refs = NULL;
|
||||
size_t refs_len = 0;
|
||||
amduat_tgk_store_mem_artifact_t *artifacts = NULL;
|
||||
size_t artifacts_len = 0;
|
||||
size_t i;
|
||||
|
||||
if (fs == NULL || manifest_path == NULL || asl_store == NULL) {
|
||||
|
|
@ -173,6 +224,10 @@ bool amduat_tgk_store_fs_init(amduat_tgk_store_fs_t *fs,
|
|||
}
|
||||
memset(fs, 0, sizeof(*fs));
|
||||
|
||||
if (!amduat_tgk_store_fs_id_space_valid(config.id_space)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!amduat_tgk_store_fs_load_manifest(manifest_path,
|
||||
manifest_format,
|
||||
&refs,
|
||||
|
|
@ -191,23 +246,49 @@ bool amduat_tgk_store_fs_init(amduat_tgk_store_fs_t *fs,
|
|||
|
||||
for (i = 0; i < refs_len; ++i) {
|
||||
amduat_asl_store_error_t err;
|
||||
artifacts[i].ref = refs[i];
|
||||
artifacts[i].artifact = amduat_artifact(amduat_octets(NULL, 0));
|
||||
err = amduat_asl_store_get(asl_store, refs[i], &artifacts[i].artifact);
|
||||
amduat_artifact_t artifact = amduat_artifact(amduat_octets(NULL, 0));
|
||||
bool duplicate = false;
|
||||
bool conflict = false;
|
||||
size_t j;
|
||||
|
||||
err = amduat_asl_store_get(asl_store, refs[i], &artifact);
|
||||
if (err != AMDUAT_ASL_STORE_OK) {
|
||||
size_t j;
|
||||
for (j = 0; j < i; ++j) {
|
||||
amduat_tgk_store_fs_artifact_bytes_free(&artifacts[j]);
|
||||
}
|
||||
amduat_asl_ref_list_free(refs, refs_len);
|
||||
free(artifacts);
|
||||
return false;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (j = 0; j < artifacts_len; ++j) {
|
||||
if (!amduat_reference_eq(artifacts[j].ref, refs[i])) {
|
||||
continue;
|
||||
}
|
||||
duplicate = true;
|
||||
if (!amduat_tgk_store_fs_artifact_eq(artifacts[j].artifact, artifact)) {
|
||||
conflict = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (conflict) {
|
||||
free((void *)artifact.bytes.data);
|
||||
goto cleanup;
|
||||
}
|
||||
if (duplicate) {
|
||||
free((void *)artifact.bytes.data);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!amduat_tgk_store_fs_reference_clone(refs[i],
|
||||
&artifacts[artifacts_len].ref)) {
|
||||
free((void *)artifact.bytes.data);
|
||||
goto cleanup;
|
||||
}
|
||||
artifacts[artifacts_len].artifact = artifact;
|
||||
artifacts_len++;
|
||||
}
|
||||
|
||||
free(refs);
|
||||
amduat_asl_ref_list_free(refs, refs_len);
|
||||
refs = NULL;
|
||||
fs->artifacts = artifacts;
|
||||
fs->artifacts_len = refs_len;
|
||||
fs->artifacts_len = artifacts_len;
|
||||
|
||||
if (!amduat_tgk_store_mem_init(&fs->mem, config, fs->artifacts,
|
||||
fs->artifacts_len)) {
|
||||
|
|
@ -215,6 +296,16 @@ bool amduat_tgk_store_fs_init(amduat_tgk_store_fs_t *fs,
|
|||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
cleanup:
|
||||
if (refs != NULL) {
|
||||
amduat_asl_ref_list_free(refs, refs_len);
|
||||
}
|
||||
for (i = 0; i < artifacts_len; ++i) {
|
||||
amduat_tgk_store_fs_artifact_full_free(&artifacts[i]);
|
||||
}
|
||||
free(artifacts);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool amduat_tgk_store_fs_init_with_asl_fs(
|
||||
|
|
|
|||
|
|
@ -387,6 +387,225 @@ cleanup:
|
|||
return exit_code;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
return test_manifest_load();
|
||||
static int test_init_rejects_duplicate_hash_id(void) {
|
||||
amduat_asl_store_config_t asl_config;
|
||||
amduat_asl_store_fs_t asl_fs;
|
||||
amduat_asl_store_t asl_store;
|
||||
amduat_tgk_store_config_t tgk_config;
|
||||
amduat_tgk_store_fs_t fs;
|
||||
amduat_tgk_identity_domain_t domains[2];
|
||||
char *root = NULL;
|
||||
char *manifest_path = NULL;
|
||||
int exit_code = 1;
|
||||
|
||||
memset(&tgk_config, 0, sizeof(tgk_config));
|
||||
memset(&fs, 0, sizeof(fs));
|
||||
|
||||
root = make_temp_root();
|
||||
if (root == NULL) {
|
||||
fprintf(stderr, "dup hash temp root failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
if (!join_path(root, "manifest.txt", &manifest_path)) {
|
||||
fprintf(stderr, "dup hash manifest path failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
if (!write_manifest(manifest_path, NULL, 0)) {
|
||||
fprintf(stderr, "dup hash manifest write failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
asl_config.encoding_profile_id = AMDUAT_ENC_ASL1_CORE_V1;
|
||||
asl_config.hash_id = AMDUAT_HASH_ASL1_ID_SHA256;
|
||||
if (!amduat_asl_store_fs_init(&asl_fs, asl_config, root)) {
|
||||
fprintf(stderr, "dup hash asl store fs init failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
amduat_asl_store_init(&asl_store, asl_config, amduat_asl_store_fs_ops(),
|
||||
&asl_fs);
|
||||
|
||||
domains[0].encoding_profile = AMDUAT_ENC_ASL1_CORE_V1;
|
||||
domains[0].hash_id = AMDUAT_HASH_ASL1_ID_SHA256;
|
||||
domains[1].encoding_profile = AMDUAT_ENC_ASL1_CORE_V1;
|
||||
domains[1].hash_id = AMDUAT_HASH_ASL1_ID_SHA256;
|
||||
|
||||
tgk_config.id_space.domains = domains;
|
||||
tgk_config.id_space.domains_len = 2;
|
||||
|
||||
if (amduat_tgk_store_fs_init(&fs, tgk_config, manifest_path,
|
||||
AMDUAT_FORMAT_REF_HEX, &asl_store)) {
|
||||
fprintf(stderr, "dup hash init accepted\n");
|
||||
amduat_tgk_store_fs_free(&fs);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
exit_code = 0;
|
||||
|
||||
cleanup:
|
||||
free(manifest_path);
|
||||
if (root != NULL) {
|
||||
remove_tree(root);
|
||||
}
|
||||
free(root);
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
static int test_manifest_duplicate_refs(void) {
|
||||
amduat_asl_store_config_t asl_config;
|
||||
amduat_asl_store_fs_t asl_fs;
|
||||
amduat_asl_store_t asl_store;
|
||||
amduat_tgk_store_config_t tgk_config;
|
||||
amduat_tgk_store_t store;
|
||||
amduat_tgk_store_fs_t fs;
|
||||
amduat_tgk_identity_domain_t domains[1];
|
||||
uint32_t edge_tags[1];
|
||||
amduat_tgk_edge_type_id_t edge_types[1];
|
||||
amduat_asl_encoding_profile_id_t encodings[1];
|
||||
amduat_octets_t edge_bytes;
|
||||
amduat_reference_t ref_edge;
|
||||
amduat_reference_t node_a;
|
||||
amduat_reference_t node_b;
|
||||
amduat_reference_t payload;
|
||||
uint8_t digest_node_a[32];
|
||||
uint8_t digest_node_b[32];
|
||||
uint8_t digest_payload[32];
|
||||
amduat_tgk_graph_scan_result_t scan;
|
||||
amduat_tgk_edge_body_t body;
|
||||
amduat_tgk_edge_body_t edge;
|
||||
amduat_reference_t edge_from[1];
|
||||
amduat_reference_t edge_to[1];
|
||||
char *root = NULL;
|
||||
char *manifest_path = NULL;
|
||||
int exit_code = 1;
|
||||
bool fs_ready = false;
|
||||
|
||||
memset(&tgk_config, 0, sizeof(tgk_config));
|
||||
memset(&fs, 0, sizeof(fs));
|
||||
memset(&body, 0, sizeof(body));
|
||||
edge_bytes = amduat_octets(NULL, 0);
|
||||
|
||||
root = make_temp_root();
|
||||
if (root == NULL) {
|
||||
fprintf(stderr, "dup refs temp root failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
if (!join_path(root, "manifest.txt", &manifest_path)) {
|
||||
fprintf(stderr, "dup refs manifest path failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
asl_config.encoding_profile_id = AMDUAT_ENC_ASL1_CORE_V1;
|
||||
asl_config.hash_id = AMDUAT_HASH_ASL1_ID_SHA256;
|
||||
if (!amduat_asl_store_fs_init(&asl_fs, asl_config, root)) {
|
||||
fprintf(stderr, "dup refs asl store fs init failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
amduat_asl_store_init(&asl_store, asl_config, amduat_asl_store_fs_ops(),
|
||||
&asl_fs);
|
||||
|
||||
domains[0].encoding_profile = AMDUAT_ENC_ASL1_CORE_V1;
|
||||
domains[0].hash_id = AMDUAT_HASH_ASL1_ID_SHA256;
|
||||
edge_tags[0] = TYPE_TAG_TGK1_EDGE_V1;
|
||||
edge_types[0] = 0x10;
|
||||
encodings[0] = TGK1_EDGE_ENC_V1;
|
||||
|
||||
tgk_config.id_space.domains = domains;
|
||||
tgk_config.id_space.domains_len = 1;
|
||||
tgk_config.artifact_scope.description = amduat_octets(NULL, 0);
|
||||
tgk_config.tgk_profiles.edge_tags = edge_tags;
|
||||
tgk_config.tgk_profiles.edge_tags_len = 1;
|
||||
tgk_config.tgk_profiles.edge_types = edge_types;
|
||||
tgk_config.tgk_profiles.edge_types_len = 1;
|
||||
tgk_config.tgk_profiles.encodings = encodings;
|
||||
tgk_config.tgk_profiles.encodings_len = 1;
|
||||
|
||||
node_a = make_ref(0xa1, digest_node_a);
|
||||
node_b = make_ref(0xb1, digest_node_b);
|
||||
payload = make_ref(0xe1, digest_payload);
|
||||
|
||||
memset(&edge, 0, sizeof(edge));
|
||||
edge.type = 0x10;
|
||||
edge_from[0] = node_a;
|
||||
edge.from = edge_from;
|
||||
edge.from_len = 1;
|
||||
edge_to[0] = node_b;
|
||||
edge.to = edge_to;
|
||||
edge.to_len = 1;
|
||||
edge.payload = payload;
|
||||
|
||||
if (!amduat_enc_tgk1_edge_encode_v1(&edge, &edge_bytes)) {
|
||||
fprintf(stderr, "dup refs edge encode failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (amduat_asl_store_put(
|
||||
&asl_store,
|
||||
amduat_artifact_with_type(edge_bytes,
|
||||
amduat_type_tag(TYPE_TAG_TGK1_EDGE_V1)),
|
||||
&ref_edge) != AMDUAT_ASL_STORE_OK) {
|
||||
fprintf(stderr, "dup refs asl store put failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
{
|
||||
amduat_reference_t refs[2];
|
||||
refs[0] = ref_edge;
|
||||
refs[1] = ref_edge;
|
||||
if (!write_manifest(manifest_path, refs, 2)) {
|
||||
fprintf(stderr, "dup refs manifest write failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
if (!amduat_tgk_store_fs_init(&fs, tgk_config, manifest_path,
|
||||
AMDUAT_FORMAT_REF_HEX, &asl_store)) {
|
||||
fprintf(stderr, "dup refs tgk store fs init failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
fs_ready = true;
|
||||
amduat_tgk_store_init(&store, tgk_config, amduat_tgk_store_fs_ops(), &fs);
|
||||
|
||||
if (amduat_tgk_store_resolve_edge(&store, ref_edge, &body) != 0) {
|
||||
fprintf(stderr, "dup refs resolve_edge failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
amduat_tgk_edge_body_free(&body);
|
||||
memset(&body, 0, sizeof(body));
|
||||
|
||||
if (!amduat_tgk_store_scan_edges(&store,
|
||||
(amduat_tgk_edge_type_filter_t){0},
|
||||
amduat_octets(NULL, 0), false, &scan)) {
|
||||
fprintf(stderr, "dup refs scan_edges failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
if (scan.edges.len != 1) {
|
||||
fprintf(stderr, "dup refs scan_edges count mismatch\n");
|
||||
amduat_tgk_graph_scan_result_free(&scan);
|
||||
goto cleanup;
|
||||
}
|
||||
amduat_tgk_graph_scan_result_free(&scan);
|
||||
exit_code = 0;
|
||||
|
||||
cleanup:
|
||||
amduat_tgk_edge_body_free(&body);
|
||||
if (fs_ready) {
|
||||
amduat_tgk_store_fs_free(&fs);
|
||||
}
|
||||
free((void *)edge_bytes.data);
|
||||
free_ref(&ref_edge);
|
||||
free(manifest_path);
|
||||
if (root != NULL) {
|
||||
remove_tree(root);
|
||||
}
|
||||
free(root);
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
if (test_manifest_load() != 0 ||
|
||||
test_init_rejects_duplicate_hash_id() != 0 ||
|
||||
test_manifest_duplicate_refs() != 0) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue