libqaeda

Unnamed repository; edit this file 'description' to name the repository.
Info | Log | Files | Refs | README | LICENSE

commit cd9d4c42e80622b8a15b28bef31055b3779e2e51
parent 88e9c3394b57b04c7003ccc8c0cf78623e964661
Author: lash <dev@holbrook.no>
Date:   Sat, 19 Apr 2025 15:50:46 +0100

Add envelope serialization

Diffstat:
Msrc/asn1/defs.txt | 2+-
Msrc/lq/envelope.c | 77++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Msrc/lq/envelope.h | 5+++--
Msrc/test/Makefile | 4++--
Msrc/test/test_envelope.c | 2+-
5 files changed, 81 insertions(+), 9 deletions(-)

diff --git a/src/asn1/defs.txt b/src/asn1/defs.txt @@ -23,7 +23,7 @@ Qaeda DEFINITIONS EXPLICIT TAGS ::= BEGIN Envelope ::= SEQUENCE { hint INTEGER, - cert Cert, + cert ANY, attach SEQUENCE OF OCTET STRING OPTIONAL } diff --git a/src/lq/envelope.c b/src/lq/envelope.c @@ -6,8 +6,11 @@ #include <lq/cert.h> #include <lq/mem.h> #include <lq/err.h> +#include <debug.h> +extern asn1_node asn; + static struct lq_attach *lq_attach_new() { struct lq_attach *o; @@ -28,6 +31,24 @@ static struct lq_attach *lq_attach_add(struct lq_attach *attach, const char *dat return attach->next; } +static int lq_envelope_get(struct lq_envelope *env, char *out, size_t *out_len) { + struct lq_attach *attach; + + attach = env->attach_start; + if (attach == NULL) { + return ERR_NOENT; + } + lq_cpy(out, attach->data, attach->len); + *out_len = attach->len; + lq_free(attach->data); + if (attach->next == NULL) { + return ERR_NOENT; + } + env->attach_start = attach->next; + lq_free(attach); + return ERR_OK; +} + static void lq_attach_free(struct lq_attach *attach) { if (attach->next != NULL) { lq_attach_free(attach->next); @@ -58,23 +79,73 @@ int lq_envelope_attach(LQEnvelope *env, const char *data, size_t data_len) { return ERR_OK; } -int lq_envelope_serialize(LQEnvelope *env, const char *out, size_t out_len) { +// TODO: DRY +static int asn_except(asn1_node *node, int err) { + int r; + + r = asn1_delete_structure(node); + if (r != ASN1_SUCCESS) { + debug_logerr(LLOG_ERROR, ERR_FAIL, asn1_strerror(err)); + } + + return err; +} + +int lq_envelope_serialize(LQEnvelope *env, LQResolve *resolve, const char *out, size_t *out_len) { + size_t c; int mx; int r; + char err[LQ_ERRSIZE]; + char buf[LQ_BLOCKSIZE]; + char node_seq_name[64]; asn1_node item; + mx = *out_len; + *out_len = 0; + lq_zero(&item, sizeof(item)); + r = asn1_create_element(asn, "Qaeda", &item); if (r != ASN1_SUCCESS) { return ERR_READ; } c = sizeof(int); - r = asn1_write_value(item, "Envelope.hint", env->hint, c); + r = asn1_write_value(item, "Envelope.hint", &env->hint, c); + if (r != ASN1_SUCCESS) { + return asn_except(&item, ERR_WRITE); + } + + c = mx - sizeof(int); + r = lq_certificate_serialize(env->cert, resolve, buf, &c); + if (r != ERR_OK) { + return asn_except(&item, r); + } + *out_len += c; + if (*out_len > mx) { + return asn_except(&item, ERR_OVERFLOW); + } + r = asn1_write_value(item, "Envelope.cert", buf, c); if (r != ASN1_SUCCESS) { return asn_except(&item, ERR_WRITE); } - //*out_len = mx; + while(1) { + c = LQ_BLOCKSIZE; + r = lq_envelope_get(env, buf, &c); + if (r) { + break; + } + r = asn1_write_value(item, "Envelope.attach", "NEW", 1); + if (r != ASN1_SUCCESS) { + return asn_except(&item, ERR_WRITE); + } + r = asn1_write_value(item, "Envelope.attach.?LAST", buf, c); + if (r != ASN1_SUCCESS) { + return asn_except(&item, ERR_WRITE); + } + } + + *out_len = mx; r = asn1_der_coding(item, "Envelope", out, (int*)out_len, err); if (r != ASN1_SUCCESS) { return asn_except(&item, ERR_ENCODING); diff --git a/src/lq/envelope.h b/src/lq/envelope.h @@ -15,6 +15,7 @@ struct lq_envelope { LQCert *cert; struct lq_attach *attach_start; struct lq_attach *attach_cur; + struct lq_attach *attach; }; typedef struct lq_envelope LQEnvelope; @@ -31,8 +32,8 @@ LQEnvelope *lq_envelope_new(LQCert *cert, int hint); * \return ERR_OK on success. */ int lq_envelope_attach(LQEnvelope *env, const char *data, size_t data_len); -int lq_envelope_serialize(LQEnvelope *env, const char *data, size_t *data_len); -int lq_envelope_deserialize(LQEnvelope **env, const char *data, size_t data_len); +int lq_envelope_serialize(LQEnvelope *env, LQResolve *resolve, const char *data, size_t *data_len); +int lq_envelope_deserialize(LQEnvelope **env, LQResolve *resolve, const char *data, size_t data_len); void lq_envelope_free(LQEnvelope *env); #endif // LIBQAEDA_ENVELOPE_H_ diff --git a/src/test/Makefile b/src/test/Makefile @@ -7,8 +7,8 @@ LIBS := ../asn1/defs_asn1_tab.o `pkg-config --libs libtasn1 libgcrypt` -L.. -L.. LDFLAGS := -lcheck $(LIBS) COMMONOBJS = ../mem/std.o ../lq/config.o ../lq/err.o ../lq/base.o ../debug.o -#all: build all-tests -all: build one-test +all: build all-tests +#all: build one-test all-tests: cK_FORK=no LD_LIBRARY_PATH=`realpath ../aux/lib` ./test_test_bin diff --git a/src/test/test_envelope.c b/src/test/test_envelope.c @@ -41,7 +41,7 @@ START_TEST(check_envelope) { ck_assert_int_eq(r, 0); c = sizeof(buf); - r = lq_envelope_serialize(env, buf, &b) + r = lq_envelope_serialize(env, NULL, buf, &c); ck_assert_int_eq(r, 0); lq_envelope_free(env);