commit 5def2300e1a3052a8e32d4928a82994d97344831
parent 720f628fe3f7f989909d77471f1832cff2d81bea
Author: lash <dev@holbrook.no>
Date: Sat, 19 Apr 2025 13:21:43 +0100
WIP add option for literal message
Diffstat:
8 files changed, 130 insertions(+), 39 deletions(-)
diff --git a/src/Makefile b/src/Makefile
@@ -50,6 +50,9 @@ clean:
make -C crypto clean
rm -vf *.o *.a *.so
+tools:
+ make -C tools
+
#shared-gpg: core aux asn1 gpg
#make -C aux/liblash/src lib
#$(CC) $(CFLAGS) -shared -o libqaeda.so $(LIBOBJFILES) $(LIBOBJEMBED)
diff --git a/src/asn1/defs.txt b/src/asn1/defs.txt
@@ -1,5 +1,6 @@
Qaeda DEFINITIONS EXPLICIT TAGS ::= BEGIN
Msg ::= SEQUENCE {
+ literal BOOLEAN,
data OCTET STRING,
--- timestamp GeneralizedTime,
timestamp OCTET STRING,
@@ -19,5 +20,4 @@ Qaeda DEFINITIONS EXPLICIT TAGS ::= BEGIN
--- parent ANY OPTIONAL
parent OCTET STRING OPTIONAL
}
-
END
diff --git a/src/cli/main.c b/src/cli/main.c
@@ -150,7 +150,7 @@ int main(int argc, char **argv) {
}
out_len = LQ_BLOCKSIZE;
- r = lq_certificate_serialize(cert, out, &out_len, NULL);
+ r = lq_certificate_serialize(cert, NULL, out, &out_len);
if (r != ERR_OK) {
lq_certificate_free(cert);
lq_ui_free();
@@ -158,7 +158,7 @@ int main(int argc, char **argv) {
}
lq_certificate_free(cert);
- r = lq_certificate_deserialize(&cert, out, out_len, NULL);
+ r = lq_certificate_deserialize(&cert, NULL, out, out_len);
if (r != ERR_OK) {
lq_ui_free();
return 1;
diff --git a/src/io/std.c b/src/io/std.c
@@ -32,6 +32,10 @@ int lq_read(int f, void *buf, size_t c) {
return read(f, buf, c);
}
+int lq_write(int f, void *buf, size_t c) {
+ return write(f, buf, c);
+}
+
void lq_close(int fd) {
close(fd);
}
diff --git a/src/lq/io.h b/src/lq/io.h
@@ -19,6 +19,7 @@ char* mktempdir(char *s);
char* ensuredir(char *s);
int lq_open(const char *pathname, int flags, int mode);
int lq_read(int f, char *buf, int c);
+int lq_write(int f, char *buf, int c);
int lq_files(const char *path, char **files, size_t files_len);
int lq_files_pfx(const char *path, char **files, size_t files_len, const char *prefix, size_t prefix_len);
void lq_close(int fd);
diff --git a/src/lq/msg.c b/src/lq/msg.c
@@ -1,4 +1,5 @@
#include <stddef.h>
+#include <string.h>
#include <time.h>
#include <libtasn1.h>
#include <endian.h>
@@ -31,7 +32,8 @@ LQMsg* lq_msg_new(const char *msg_data, size_t msg_len) {
msg->data = lq_alloc(msg_len);
lq_cpy(msg->data, msg_data, msg_len);
msg->len = msg_len;
- msg->state = LQ_MSG_INIT;
+ //msg->state = LQ_MSG_INIT;
+ msg->state = LQ_MSG_INIT | LQ_MSG_LITERAL;
return msg;
}
@@ -127,13 +129,14 @@ int lq_msg_serialize(LQMsg *msg, LQResolve *resolve, char *out, size_t *out_len)
size_t c;
int r;
size_t mx;
- char tmp[LQ_DIGEST_LEN];
+ char tmp[LQ_CRYPTO_BUFLEN];
char timedata[8];
char err[1024];
LQPubKey *pubkey;
LQResolve *resolve_active;
asn1_node item;
char *keydata;
+ char v[6];
mx = *out_len;
*out_len = 0;
@@ -145,41 +148,63 @@ int lq_msg_serialize(LQMsg *msg, LQResolve *resolve, char *out, size_t *out_len)
return ERR_READ;
}
- c = LQ_DIGEST_LEN;
- *out_len += c;
- if (*out_len > mx) {
- return asn_except(&item, ERR_OVERFLOW);
+ lq_cpy(v, "FALSE", 5);
+ v[5] = 0;
+ if (msg->state & LQ_MSG_LITERAL) {
+ lq_cpy(v, "TRUE", 5);
+ v[4] = 0;
+ }
+ r = asn1_write_value(item, "Msg.literal", v, strlen(v) + 1);
+ if (r != ASN1_SUCCESS) {
+ return asn_except(&item, ERR_WRITE);
}
- if (msg->state & LQ_MSG_INIT) {
- r = lq_digest(msg->data, msg->len, tmp);
- if (r != ERR_OK) {
- return asn_except(&item, r);
- }
+ *out_len = 1;
- resolve_active = resolve;
- while (resolve_active != NULL) {
- r = resolve_active->store->put(LQ_CONTENT_MSG, resolve_active->store, tmp, &c, msg->data, msg->len);
+ if (msg->state & LQ_MSG_INIT) {
+ if (msg->state & LQ_MSG_LITERAL) {
+ lq_cpy(tmp, msg->data, msg->len);
+ c = msg->len;
+ *out_len += c;
+ if (*out_len > mx) {
+ return asn_except(&item, ERR_OVERFLOW);
+ }
+ } else {
+ c = LQ_DIGEST_LEN;
+ *out_len += c;
+ if (*out_len > mx) {
+ return asn_except(&item, ERR_OVERFLOW);
+ }
+ r = lq_digest(msg->data, msg->len, tmp);
if (r != ERR_OK) {
return asn_except(&item, r);
}
- resolve_active = resolve_active->next;
- msg->state |= LQ_MSG_RESOLVED;
+
+ resolve_active = resolve;
+ while (resolve_active != NULL) {
+ r = resolve_active->store->put(LQ_CONTENT_MSG, resolve_active->store, tmp, &c, msg->data, msg->len);
+ if (r != ERR_OK) {
+ return asn_except(&item, r);
+ }
+ resolve_active = resolve_active->next;
+ msg->state |= LQ_MSG_RESOLVED;
+ }
+ if (!(msg->state & LQ_MSG_RESOLVED)) {
+ debug(LLOG_DEBUG, "msg", "no resolver");
+ }
}
} else {
tmp[0] = 0;
c = 1;
}
- if (!(msg->state & LQ_MSG_RESOLVED)) {
- debug(LLOG_DEBUG, "msg", "no resolver");
- }
r = asn1_write_value(item, "Msg.data", tmp, c);
if (r != ASN1_SUCCESS) {
return asn_except(&item, ERR_WRITE);
}
+
lq_cpy(timedata, &msg->time.tv_sec, 4);
lq_cpy(((char*)timedata)+4, &msg->time.tv_nsec, 4);
r = to_endian(TO_ENDIAN_BIG, 4, timedata);
@@ -230,18 +255,25 @@ int lq_msg_serialize(LQMsg *msg, LQResolve *resolve, char *out, size_t *out_len)
return ERR_OK;
}
+/**
+ * \todo allow for 1 byte message
+ */
int lq_msg_deserialize(LQMsg **msg, LQResolve *resolve, const char *in, size_t in_len) {
int r;
size_t c;
size_t l;
+ char v[6];
char resolved;
char err[LQ_ERRSIZE];
char z[LQ_DIGEST_LEN];
char tmp[LQ_BLOCKSIZE];
+ char *p;
+ char msg_state;
asn1_node item;
LQResolve *resolve_active;
resolved = 0;
+ msg_state = 0;
lq_zero(&item, sizeof(item));
@@ -255,7 +287,18 @@ int lq_msg_deserialize(LQMsg **msg, LQResolve *resolve, const char *in, size_t i
return asn_except(&item, ERR_ENCODING);
}
- c = LQ_DIGEST_LEN;
+ c = 6;
+ r = asn1_read_value(item, "literal", v, (int*)&c);
+ if (r != ASN1_SUCCESS) {
+ debug_logerr(LLOG_WARNING, ERR_READ, (char*)asn1_strerror(r));
+ return asn_except(&item, ERR_READ);
+ }
+ if (lq_cmp(v, "F", 1)) {
+ msg_state |= LQ_MSG_LITERAL;
+ }
+
+ //c = LQ_DIGEST_LEN;
+ c = LQ_BLOCKSIZE;
r = asn1_read_value(item, "data", z, (int*)&c);
if (r != ASN1_SUCCESS) {
debug_logerr(LLOG_WARNING, ERR_READ, (char*)asn1_strerror(r));
@@ -268,30 +311,31 @@ int lq_msg_deserialize(LQMsg **msg, LQResolve *resolve, const char *in, size_t i
return ERR_OK;
}
- lq_cpy(tmp, z, c);
- l = c;
-
- c = LQ_BLOCKSIZE;
- resolve_active = resolve;
- while (resolve_active != NULL) {
- r = resolve_active->store->get(LQ_CONTENT_MSG, resolve_active->store, z, LQ_DIGEST_LEN, tmp, &c);
- if (r != ERR_OK) {
- return asn_except(&item, r);
+ if (!(msg_state & LQ_MSG_LITERAL)) {
+ resolve_active = resolve;
+ lq_cpy(tmp, z, c);
+ l = c;
+ c = LQ_BLOCKSIZE;
+ while (resolve_active != NULL) {
+ r = resolve_active->store->get(LQ_CONTENT_MSG, resolve_active->store, z, LQ_DIGEST_LEN, tmp, &c);
+ if (r != ERR_OK) {
+ return asn_except(&item, r);
+ }
+ resolve_active = resolve_active->next;
+ resolved = LQ_MSG_RESOLVED;
}
- resolve_active = resolve_active->next;
- resolved = LQ_MSG_RESOLVED;
- }
- if (!(resolved & LQ_MSG_RESOLVED)) {
- debug(LLOG_DEBUG, "msg", "no resolver");
- c = l;
+ if (!(resolved & LQ_MSG_RESOLVED)) {
+ debug(LLOG_DEBUG, "msg", "no resolver");
+ c = l;
+ }
}
*msg = lq_msg_new((const char*)tmp, c);
if (*msg == NULL) {
return asn_except(&item, ERR_MEM);
}
- (*msg)->state = resolved;
+ (*msg)->state = msg_state | resolved;
/// \todo document timestamp size
c = 8;
diff --git a/src/lq/msg.h b/src/lq/msg.h
@@ -10,6 +10,7 @@
enum lq_msgstate_e {
LQ_MSG_INIT = 1,
LQ_MSG_RESOLVED = 2,
+ LQ_MSG_LITERAL = 4,
};
/**
@@ -118,4 +119,18 @@ int lq_msg_deserialize(LQMsg **msg, LQResolve *resolve, const char *in, size_t i
*/
void lq_msg_free(LQMsg *msg);
+/**
+ * \brief Serialize message content.
+ *
+ * \param[in] Content to serialize.
+ * \param[in] Length of content
+ * \param[out] Output buffer
+ * \param[in/out] Length of output buffer, will be overwritten by length of serialized data.
+ *
+ * \return ERR_OK on success.
+ *
+ * \see lq_msg_serialize
+ */
+int lq_attach_serialize(const char *in, size_t in_len, char *out, size_t *out_len);
+
#endif // LIBQAEDA_MSG_H_
diff --git a/src/test/test_cert.c b/src/test/test_cert.c
@@ -257,6 +257,29 @@ START_TEST(check_cert_symmetric_ser_rsp_bothsig) {
lq_certificate_free(cert);
}
END_TEST
+//
+//START_TEST(check_cert_attach) {
+// int r;
+// size_t c;
+// size_t l;
+// LQCert *cert;
+// char buf[LQ_BLOCKSIZE];
+// char *p;
+//
+// cert = lq_certificate_new(NULL);
+// ck_assert_ptr_nonnull(cert);
+// c = LQ_BLOCKSIZE;
+// r = lq_certificate_serialize(cert, NULL, buf, &c);
+// ck_assert_int_eq(r, 0);
+// lq_certificate_free(cert);
+//
+// r = lq_certificate_deserialize(&cert, NULL, buf, l);
+// ck_assert_int_eq(r, 0);
+// lq_certificate_free(cert);
+//}
+//END_TEST
+
+
Suite * common_suite(void) {
Suite *s;
@@ -274,6 +297,7 @@ Suite * common_suite(void) {
tcase_add_test(tc, check_cert_symmetric_ser_req_sig);
tcase_add_test(tc, check_cert_symmetric_ser_rsp_onesig);
tcase_add_test(tc, check_cert_symmetric_ser_rsp_bothsig);
+// tcase_add_test(tc, check_cert_attach);
suite_add_tcase(s, tc);
return s;