libqaeda

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

commit 57172c240d9b36864db942d22f16d747f5baad75
parent feb7425a8ddc5b5a43adffca2e17bfc08a345cba
Author: lash <dev@holbrook.no>
Date:   Sun,  2 Mar 2025 14:43:10 +0000

Add cert tests

Diffstat:
Msrc/Makefile | 11+++++++++--
Msrc/asn1/defs.txt | 16+++++++++-------
Msrc/crypto/Makefile | 5+++++
Msrc/lq/Makefile | 5+++++
Msrc/lq/cert.c | 177++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Msrc/lq/cert.h | 3++-
Msrc/lq/msg.c | 26+++++++++++++-------------
Msrc/lq/msg.h | 4++--
Msrc/mem/Makefile | 5+++++
Msrc/test/Makefile | 5+++++
Msrc/test/test_cert.c | 117+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
11 files changed, 346 insertions(+), 28 deletions(-)

diff --git a/src/Makefile b/src/Makefile @@ -1,6 +1,6 @@ -all: asn1 core dummy +all: core dummy -core: +core: asn1 make -C lq asn1: @@ -11,3 +11,10 @@ dummy: test: core dummy make -C test + +clean: + make -C asn1 clean + make -C lq clean + make -C test clean + make -C mem clean + make -C crypto clean diff --git a/src/asn1/defs.txt b/src/asn1/defs.txt @@ -6,16 +6,18 @@ Qaeda DEFINITIONS EXPLICIT TAGS ::= BEGIN pubkey OCTET STRING } + NoParent ::= OCTET STRING + Cert ::= SEQUENCE { domain OCTET STRING, - request Msg, +--- TODO: why cant request be Msg type, fails write + request ANY, request_sig OCTET STRING, - response Msg, - response_sig OCTET STRING + response ANY, + response_sig OCTET STRING, +--- TODO: replace parent with no parent obj adn set type ANY +--- parent ANY OPTIONAL + parent OCTET STRING OPTIONAL } - CertEntry ::= SEQUENCE { - parent Cert, - this Cert, - } END diff --git a/src/crypto/Makefile b/src/crypto/Makefile @@ -3,3 +3,8 @@ CFLAGS += $(INCLUDES) -Wall dummy: $(CC) $(CFLAGS) -g3 -c dummy.c + +clean: + rm -vf *.o + +.PHONY: clean diff --git a/src/lq/Makefile b/src/lq/Makefile @@ -9,3 +9,8 @@ LDFLAGS += $(LIBS) $(CC) $(CFLAGS) -c $< -o $@ $(LDFLAGS) all: $(OBJS) + +clean: + rm -vf *.o + +.PHONY: clean diff --git a/src/lq/cert.c b/src/lq/cert.c @@ -6,13 +6,30 @@ #include "lq/wire.h" #include "lq/err.h" -static LQCert noparent; +static LQPubKey nokey = { + .pk = 0, + .lokey = "", + .lolen = 0, +}; +static LQCert noparent = { + .parent = 0, + .request = 0, + .request_sig = 0, + .response = 0, + .response_sig = 0, + .ctx = 0, +}; static LQMsg nomsg = { .data = "", .len = 0, .time.tv_sec = 0, .time.tv_nsec = 0, }; +static LQSig nosig = { + .pubkey = &nokey, + .losig = "", + .lolen = 0, +}; LQCert* lq_certificate_new(LQCert *parent, LQCtx *ctx, LQMsg *req, LQMsg *rsp) { LQCert *cert; @@ -24,13 +41,19 @@ LQCert* lq_certificate_new(LQCert *parent, LQCtx *ctx, LQMsg *req, LQMsg *rsp) { cert->parent = &noparent; } cert->request = req; + cert->request_sig = NULL; cert->response = rsp; + cert->response_sig = NULL; cert->ctx = ctx; lq_set(cert->domain, 0, LQ_CERT_DOMAIN_LEN); return cert; } +void lq_certificate_set_domain(LQCert *cert, const char *domain) { + lq_cpy(cert->domain, domain, LQ_CERT_DOMAIN_LEN); +} + int lq_certificate_serialize(LQCert *cert, char *out, size_t *out_len) { size_t c; int r; @@ -38,6 +61,7 @@ int lq_certificate_serialize(LQCert *cert, char *out, size_t *out_len) { char err[1024]; char buf[4096]; LQMsg *msg; + LQSig *sig; asn1_node node; mx = *out_len; @@ -58,6 +82,7 @@ int lq_certificate_serialize(LQCert *cert, char *out, size_t *out_len) { return ERR_WRITE; } + // Set request message if exists msg = cert->request; if (msg == NULL) { msg = &nomsg; @@ -76,6 +101,156 @@ int lq_certificate_serialize(LQCert *cert, char *out, size_t *out_len) { return ERR_WRITE; } + // Set request signature if exists + sig = cert->request_sig; + if (cert->request == NULL || sig == NULL) { + sig = &nosig; + } + // \todo proper sig serialize + c = sig->lolen; + *out_len += c; + if (*out_len > mx) { + return ERR_OVERFLOW; + } + r = asn1_write_value(node, "Qaeda.Cert.request_sig", sig->losig, c); + if (r != ASN1_SUCCESS) { + return ERR_WRITE; + } + + msg = cert->response; + if (msg == NULL) { + msg = &nomsg; + } + c = mx - LQ_CERT_DOMAIN_LEN; + r = lq_msg_serialize(msg, buf, &c); + if (r != ERR_OK) { + return r; + } + *out_len += c; + if (*out_len > mx) { + return ERR_OVERFLOW; + } + r = asn1_write_value(node, "Qaeda.Cert.response", buf, c); + if (r != ASN1_SUCCESS) { + return ERR_WRITE; + } + + // Set response signature if exists + sig = cert->response_sig; + if (cert->response == NULL || sig == NULL) { + sig = &nosig; + } + // \todo proper sig serialize + c = sig->lolen; + *out_len += c; + if (*out_len > mx) { + return ERR_OVERFLOW; + } + r = asn1_write_value(node, "Qaeda.Cert.response_sig", sig->losig, c); + if (r != ASN1_SUCCESS) { + return ERR_WRITE; + } + + c = 0; + r = asn1_write_value(node, "Qaeda.Cert.parent", &c, 1); + if (r != ASN1_SUCCESS) { + return ERR_WRITE; + } + + *out_len = mx; + r = asn1_der_coding(node, "Qaeda.Cert", out, (int*)out_len, err); + if (r != ASN1_SUCCESS) { + return ERR_ENCODING; + } + + + return ERR_OK; +} + +int lq_certificate_deserialize(LQCert **cert, char *in, size_t in_len) { + int r; + int c; + char err[1024]; + char tmp[4096]; + asn1_node node; + asn1_node item; + LQCtx *ctx; + LQCert *p; + + // \todo ctx make it make sense here + lq_set(ctx, 0, sizeof(LQCtx)); + lq_set(&node, 0, sizeof(node)); + lq_set(&item, 0, sizeof(item)); + r = asn1_array2tree(defs_asn1_tab, &node, err); + if (r != ASN1_SUCCESS) { + return ERR_INIT; + } + + r = asn1_create_element(node, "Qaeda.Cert", &item); + if (r != ASN1_SUCCESS) { + return ERR_READ; + } + + r = asn1_der_decoding(&item, in, in_len, err); + if (r != ASN1_SUCCESS) { + return ERR_ENCODING; + } + + c = LQ_CERT_DOMAIN_LEN; + r = asn1_read_value(item, "domain", tmp, &c); + if (r != ASN1_SUCCESS) { + return ERR_READ; + } + + p = lq_certificate_new(NULL, ctx, NULL, NULL); + lq_certificate_set_domain(p, tmp); + + c = 4096; + r = asn1_read_value(item, "request", tmp, &c); + if (r != ASN1_SUCCESS) { + return ERR_READ; + } + r = lq_msg_deserialize(&p->request, tmp, c); + if (r != ERR_OK) { + return r; + } + + c = 4096; + r = asn1_read_value(item, "request_sig", tmp, &c); + if (r != ASN1_SUCCESS) { + return ERR_READ; + } + if (c > 0) { + p->request_sig = lq_alloc(sizeof(LQSig)); + p->request_sig->losig = tmp; + p->request_sig->lolen = c; + // \todo deserialize pubkey from msg and insert + } + + c = 4096; + r = asn1_read_value(item, "response", tmp, &c); + if (r != ASN1_SUCCESS) { + return ERR_READ; + } + r = lq_msg_deserialize(&p->response, tmp, c); + if (r != ERR_OK) { + return r; + } + + + c = 4096; + r = asn1_read_value(item, "response_sig", tmp, &c); + if (r != ASN1_SUCCESS) { + return ERR_READ; + } + if (c > 0) { + p->response_sig = lq_alloc(sizeof(LQSig)); + p->response_sig->losig = tmp; + p->response_sig->lolen = c; + // \todo deserialize pubkey from msg and insert + } + *cert = p; + return ERR_OK; } diff --git a/src/lq/cert.h b/src/lq/cert.h @@ -23,8 +23,9 @@ struct lq_certificate_t { }; LQCert* lq_certificate_new(LQCert *parent, LQCtx *ctx, LQMsg *req, LQMsg *rsp); +void lq_certificate_set_domain(LQCert *cert, const char *domain); int lq_certificate_serialize(LQCert *cert, char *out, size_t *out_len); -int lq_certificate_deserialize(LQCert *cert, char *in, size_t in_len); +int lq_certificate_deserialize(LQCert **cert, char *in, size_t in_len); int lq_certificate_verify(LQCert *cert); void lq_certificate_free(LQCert *cert); diff --git a/src/lq/msg.c b/src/lq/msg.c @@ -29,11 +29,11 @@ LQMsg* lq_msg_new(const char *msg_data, size_t msg_len) { return msg; } -int lq_msg_sign(LQMsg *msg, LQPrivKey *pk) { +LQSig* lq_msg_sign(LQMsg *msg, LQPrivKey *pk) { return lq_msg_sign_salted(msg, pk, 0, 0); } -int lq_msg_sign_salted(LQMsg *msg, LQPrivKey *pk, const char *salt, size_t salt_len) { +LQSig* lq_msg_sign_salted(LQMsg *msg, LQPrivKey *pk, const char *salt, size_t salt_len) { int r; char *data; char digest[LQ_DIGEST_LEN]; @@ -43,8 +43,7 @@ int lq_msg_sign_salted(LQMsg *msg, LQPrivKey *pk, const char *salt, size_t salt_ msg->pubkey = lq_publickey_from_privatekey(pk); r = lq_digest(data, msg->len, (char*)digest); - - return r; + return lq_privatekey_sign(pk, msg->data, msg->len, salt, salt_len); } void lq_msg_free(LQMsg *msg) { @@ -61,6 +60,7 @@ int lq_msg_serialize(LQMsg *msg, char *out, size_t *out_len) { size_t mx; char timedata[8]; char err[1024]; + LQPubKey *pubkey; asn1_node node; mx = *out_len; @@ -102,16 +102,16 @@ int lq_msg_serialize(LQMsg *msg, char *out, size_t *out_len) { return ERR_WRITE; } - if (msg->pubkey == NULL) { - msg->pubkey = &nokey; - } else { - c = msg->pubkey->lolen; - *out_len += c; - if (*out_len > mx) { - return ERR_OVERFLOW; - } + pubkey = msg->pubkey; + if (pubkey == NULL) { + pubkey = &nokey; + } + c = pubkey->lolen; + *out_len += c; + if (*out_len > mx) { + return ERR_OVERFLOW; } - r = asn1_write_value(node, "Qaeda.Msg.pubkey", &msg->pubkey->lokey, c); + r = asn1_write_value(node, "Qaeda.Msg.pubkey", pubkey->lokey, c); if (r != ASN1_SUCCESS) { return ERR_WRITE; } diff --git a/src/lq/msg.h b/src/lq/msg.h @@ -15,8 +15,8 @@ struct lq_msg_t { typedef struct lq_msg_t LQMsg; LQMsg* lq_msg_new(const char *msg_data, size_t msg_len); -int lq_msg_sign(LQMsg *msg, LQPrivKey *pk); -int lq_msg_sign_salted(LQMsg *msg, LQPrivKey *pk, const char *salt, size_t salt_len); +LQSig* lq_msg_sign(LQMsg *msg, LQPrivKey *pk); +LQSig* lq_msg_sign_salted(LQMsg *msg, LQPrivKey *pk, const char *salt, size_t salt_len); int lq_msg_serialize(LQMsg *msg, char *out, size_t *out_len); int lq_msg_deserialize(LQMsg **msg, const char *in, size_t in_len); void lq_msg_free(LQMsg *msg); diff --git a/src/mem/Makefile b/src/mem/Makefile @@ -1,2 +1,7 @@ std: $(CC) $(CFLAGS) -g3 -c std.c + +clean: + rm -vf *.o + +.PHONY: clean diff --git a/src/test/Makefile b/src/test/Makefile @@ -16,3 +16,8 @@ build: $(CC) $(CFLAGS) $(LDFLAGS) test_msg.c -o test_msg_bin ../crypto/dummy.o ../mem/std.o ../lq/msg.o -lcheck $(CC) $(CFLAGS) $(LDFLAGS) test_cert.c -o test_cert_bin ../crypto/dummy.o ../mem/std.o ../lq/msg.o ../lq/cert.o -lcheck +clean: + rm -vf test_*_bin + rm -vf *.o + +.PHONY: clean diff --git a/src/test/test_cert.c b/src/test/test_cert.c @@ -8,9 +8,10 @@ #include "lq/crypto.h" const char *data = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."; +const char *data_two = "Que trata de la condición y ejercicio del famoso hidalgo D. Quijote de la Mancha En un lugar de la Mancha, de cuyo nombre no quiero acordarme, no ha mucho tiempo que vivía un hidalgo de los de lanza en astillero, adarga antigua, rocín flaco y galgo corredor."; -START_TEST(check_cert_symmetric) { +START_TEST(check_cert_symmetric_nomsg) { int r; size_t c; LQCert *cert; @@ -22,7 +23,115 @@ START_TEST(check_cert_symmetric) { c = 4096; r = lq_certificate_serialize(cert, buf, &c); ck_assert_int_eq(r, 0); + lq_certificate_free(cert); + + r = lq_certificate_deserialize(&cert, buf, c); + ck_assert_int_eq(r, 0); + lq_certificate_free(cert); +} +END_TEST + +START_TEST(check_cert_symmetric_req_nosig) { + int r; + size_t c; + LQCert *cert; + LQMsg *req; + LQCtx ctx; + char buf[4096]; + + lq_set(&ctx, 0, sizeof(LQCtx)); + req = lq_msg_new(data, strlen(data) + 1); + cert = lq_certificate_new(NULL, &ctx, req, NULL); + c = 4096; + r = lq_certificate_serialize(cert, buf, &c); + ck_assert_int_eq(r, 0); + lq_certificate_free(cert); + + r = lq_certificate_deserialize(&cert, buf, c); + ck_assert_int_eq(r, 0); + lq_certificate_free(cert); +} +END_TEST + +START_TEST(check_cert_symmetric_req_sig) { + int r; + size_t c; + LQCert *cert; + LQMsg *req; + LQPrivKey *pk; + LQCtx ctx; + char buf[4096]; + + pk = lq_privatekey_new(data, 32); + lq_set(&ctx, 0, sizeof(LQCtx)); + req = lq_msg_new(data, strlen(data) + 1); + cert = lq_certificate_new(NULL, &ctx, req, NULL); + // \todo change interface to certificate sign + cert->request_sig = lq_msg_sign(req, pk); + c = 4096; + r = lq_certificate_serialize(cert, buf, &c); + ck_assert_int_eq(r, 0); + lq_certificate_free(cert); + r = lq_certificate_deserialize(&cert, buf, c); + ck_assert_int_eq(r, 0); + lq_certificate_free(cert); +} +END_TEST + +START_TEST(check_cert_symmetric_rsp_onesig) { + int r; + size_t c; + LQCert *cert; + LQMsg *req; + LQMsg *rsp; + LQPrivKey *pk; + LQCtx ctx; + char buf[4096]; + + pk = lq_privatekey_new(data, 32); + lq_set(&ctx, 0, sizeof(LQCtx)); + req = lq_msg_new(data, strlen(data) + 1); + rsp = lq_msg_new(data_two, strlen(data_two) + 1); + cert = lq_certificate_new(NULL, &ctx, req, rsp); + // \todo change interface to certificate sign + cert->request_sig = lq_msg_sign(req, pk); + c = 4096; + r = lq_certificate_serialize(cert, buf, &c); + ck_assert_int_eq(r, 0); + lq_certificate_free(cert); + + r = lq_certificate_deserialize(&cert, buf, c); + ck_assert_int_eq(r, 0); + lq_certificate_free(cert); +} +END_TEST + +START_TEST(check_cert_symmetric_rsp_bothsig) { + int r; + size_t c; + LQCert *cert; + LQMsg *req; + LQMsg *rsp; + LQPrivKey *pk; + LQCtx ctx; + char buf[4096]; + + pk = lq_privatekey_new(data, 32); + lq_set(&ctx, 0, sizeof(LQCtx)); + req = lq_msg_new(data, strlen(data) + 1); + rsp = lq_msg_new(data_two, strlen(data_two) + 1); + cert = lq_certificate_new(NULL, &ctx, req, rsp); + // \todo change interface to certificate sign + cert->request_sig = lq_msg_sign(req, pk); + cert->response_sig = lq_msg_sign(rsp, pk); + c = 4096; + r = lq_certificate_serialize(cert, buf, &c); + ck_assert_int_eq(r, 0); + lq_certificate_free(cert); + + r = lq_certificate_deserialize(&cert, buf, c); + ck_assert_int_eq(r, 0); lq_certificate_free(cert); } END_TEST @@ -33,7 +142,11 @@ Suite * common_suite(void) { s = suite_create("cert"); tc = tcase_create("serialize"); - tcase_add_test(tc, check_cert_symmetric); + tcase_add_test(tc, check_cert_symmetric_nomsg); + tcase_add_test(tc, check_cert_symmetric_req_nosig); + tcase_add_test(tc, check_cert_symmetric_req_sig); + tcase_add_test(tc, check_cert_symmetric_rsp_onesig); + tcase_add_test(tc, check_cert_symmetric_rsp_bothsig); suite_add_tcase(s, tc); return s;