amduat/src/near_core/bytestore.c
Carl Niklas Rydberg 3473b19425 trow AI at it.
2026-02-22 00:25:56 +01:00

236 lines
7.3 KiB
C

#include "amduat/bytestore.h"
#include <stdlib.h>
#include <string.h>
static const char k_amduat_bytestore_domain_sep[] = "CAS:OBJ\0";
static bool amduat_bytestore_trim_trailing_slash(const char *input,
size_t *out_len) {
size_t len;
if (input == NULL || out_len == NULL) {
return false;
}
len = strlen(input);
while (len > 1u && input[len - 1u] == '/') {
len--;
}
*out_len = len;
return true;
}
static bool amduat_bytestore_path_is_prefix(const char *parent,
size_t parent_len,
const char *child,
size_t child_len) {
if (parent_len == 0u || child_len == 0u) {
return false;
}
if (child_len < parent_len) {
return false;
}
if (memcmp(parent, child, parent_len) != 0) {
return false;
}
if (child_len == parent_len) {
return true;
}
return child[parent_len] == '/';
}
void amduat_bytestore_init(amduat_bytestore_t *store,
amduat_bytestore_config_t config,
amduat_bytestore_ops_t ops,
void *ctx) {
if (store == NULL) {
return;
}
store->config = config;
store->ops = ops;
store->ctx = ctx;
}
amduat_bytestore_error_t amduat_bytestore_put(amduat_bytestore_t *store,
amduat_octets_t payload,
amduat_reference_t *out_cid) {
if (store == NULL || store->ops.put == NULL) {
return AMDUAT_BYTESTORE_ERR_UNSUPPORTED;
}
return store->ops.put(store->ctx, payload, out_cid);
}
amduat_bytestore_error_t amduat_bytestore_put_stream(
amduat_bytestore_t *store,
amduat_bytestore_stream_t stream,
amduat_reference_t *out_cid) {
if (store == NULL || store->ops.put_stream == NULL) {
return AMDUAT_BYTESTORE_ERR_UNSUPPORTED;
}
return store->ops.put_stream(store->ctx, stream, out_cid);
}
amduat_bytestore_error_t amduat_bytestore_import_cor(
amduat_bytestore_t *store,
amduat_octets_t envelope,
amduat_reference_t *out_cid) {
if (store == NULL || store->ops.import_cor == NULL) {
return AMDUAT_BYTESTORE_ERR_UNSUPPORTED;
}
return store->ops.import_cor(store->ctx, envelope, out_cid);
}
amduat_bytestore_error_t amduat_bytestore_export_cor(
amduat_bytestore_t *store,
amduat_reference_t cid,
amduat_octets_t *out_envelope) {
if (store == NULL || store->ops.export_cor == NULL) {
return AMDUAT_BYTESTORE_ERR_UNSUPPORTED;
}
return store->ops.export_cor(store->ctx, cid, out_envelope);
}
amduat_bytestore_error_t amduat_bytestore_get(amduat_bytestore_t *store,
amduat_reference_t cid,
amduat_octets_t *out_bytes) {
if (store == NULL || store->ops.get == NULL) {
return AMDUAT_BYTESTORE_ERR_UNSUPPORTED;
}
return store->ops.get(store->ctx, cid, out_bytes);
}
amduat_bytestore_error_t amduat_bytestore_stat(
amduat_bytestore_t *store,
amduat_reference_t cid,
amduat_bytestore_stat_t *out_stat) {
if (store == NULL || store->ops.stat == NULL) {
return AMDUAT_BYTESTORE_ERR_UNSUPPORTED;
}
return store->ops.stat(store->ctx, cid, out_stat);
}
amduat_bytestore_error_t amduat_bytestore_assert_area_isolation(
amduat_bytestore_t *store,
const char *public_root,
const char *secure_root) {
size_t public_len;
size_t secure_len;
if (store != NULL && store->ops.assert_area_isolation != NULL) {
return store->ops.assert_area_isolation(store->ctx, public_root,
secure_root);
}
if (!amduat_bytestore_trim_trailing_slash(public_root, &public_len) ||
!amduat_bytestore_trim_trailing_slash(secure_root, &secure_len)) {
return AMDUAT_BYTESTORE_ERR_INVALID;
}
if (public_len == 0u || secure_len == 0u) {
return AMDUAT_BYTESTORE_ERR_INVALID;
}
if (public_len == secure_len &&
memcmp(public_root, secure_root, public_len) == 0) {
return AMDUAT_BYTESTORE_ERR_AREA_VIOLATION;
}
if (amduat_bytestore_path_is_prefix(public_root, public_len, secure_root,
secure_len)) {
return AMDUAT_BYTESTORE_ERR_AREA_VIOLATION;
}
if (amduat_bytestore_path_is_prefix(secure_root, secure_len, public_root,
public_len)) {
return AMDUAT_BYTESTORE_ERR_AREA_VIOLATION;
}
return AMDUAT_BYTESTORE_OK;
}
bool amduat_bytestore_cid_for_payload(amduat_hash_id_t hash_id,
amduat_octets_t payload,
amduat_reference_t *out_cid) {
const amduat_hash_asl1_desc_t *desc;
uint8_t *digest;
amduat_octets_t domain_sep;
if (out_cid == NULL) {
return false;
}
*out_cid = amduat_reference(0, amduat_octets(NULL, 0u));
desc = amduat_hash_asl1_desc_lookup(hash_id);
if (desc == NULL || desc->digest_len == 0u) {
return false;
}
digest = (uint8_t *)malloc(desc->digest_len);
if (digest == NULL) {
return false;
}
domain_sep = amduat_octets(k_amduat_bytestore_domain_sep,
sizeof(k_amduat_bytestore_domain_sep) - 1u);
if (!amduat_hash_asl1_digest_domain(hash_id, domain_sep, payload, digest,
desc->digest_len)) {
free(digest);
return false;
}
*out_cid = amduat_reference(hash_id, amduat_octets(digest, desc->digest_len));
return true;
}
bool amduat_bytestore_cid_for_stream(amduat_hash_id_t hash_id,
amduat_bytestore_stream_t stream,
amduat_reference_t *out_cid) {
amduat_hash_asl1_stream_t hasher;
const amduat_hash_asl1_desc_t *desc;
uint8_t *digest;
amduat_octets_t domain_sep;
amduat_octets_t chunk;
int next_status;
if (out_cid == NULL || stream.next == NULL) {
return false;
}
*out_cid = amduat_reference(0, amduat_octets(NULL, 0u));
desc = amduat_hash_asl1_desc_lookup(hash_id);
if (desc == NULL || desc->digest_len == 0u) {
return false;
}
if (!amduat_hash_asl1_stream_init(hash_id, &hasher)) {
return false;
}
domain_sep = amduat_octets(k_amduat_bytestore_domain_sep,
sizeof(k_amduat_bytestore_domain_sep) - 1u);
if (!amduat_hash_asl1_stream_update(&hasher, domain_sep)) {
amduat_hash_asl1_stream_destroy(&hasher);
return false;
}
while (true) {
chunk = amduat_octets(NULL, 0u);
next_status = stream.next(stream.ctx, &chunk);
if (next_status == 0) {
break;
}
if (next_status < 0) {
amduat_hash_asl1_stream_destroy(&hasher);
return false;
}
if (chunk.len != 0u && chunk.data == NULL) {
amduat_hash_asl1_stream_destroy(&hasher);
return false;
}
if (chunk.len != 0u &&
!amduat_hash_asl1_stream_update(&hasher, chunk)) {
amduat_hash_asl1_stream_destroy(&hasher);
return false;
}
}
digest = (uint8_t *)malloc(desc->digest_len);
if (digest == NULL) {
amduat_hash_asl1_stream_destroy(&hasher);
return false;
}
if (!amduat_hash_asl1_stream_final(&hasher, digest, desc->digest_len)) {
free(digest);
amduat_hash_asl1_stream_destroy(&hasher);
return false;
}
amduat_hash_asl1_stream_destroy(&hasher);
*out_cid = amduat_reference(hash_id, amduat_octets(digest, desc->digest_len));
return true;
}