commit 74cee6f83578055f8268fbbfaf26e0ab4254039b
parent 3caac83ccd44413d0829a7c6412cf826197f5478
Author: lash <dev@holbrook.no>
Date: Sat, 10 May 2025 21:48:04 +0100
Enable retrieve public keys from certificate
Diffstat:
6 files changed, 152 insertions(+), 11 deletions(-)
diff --git a/src/lq/cert.c b/src/lq/cert.c
@@ -159,7 +159,7 @@ int lq_certificate_sign(LQCert *cert, LQPrivKey *pk) {
return ERR_OK;
}
-int lq_certificate_verify(LQCert *cert) {
+int lq_certificate_verify(LQCert *cert, LQPubKey **request_pubkey, LQPubKey **response_pubkey) {
int r;
char out[LQ_BLOCKSIZE];
LQCert cert_valid;
@@ -200,6 +200,16 @@ int lq_certificate_verify(LQCert *cert) {
return debug_logerr(LLOG_DEBUG, r, "cert verify response");
}
+ if (request_pubkey != NULL) {
+ *request_pubkey = cert->request_sig->pubkey;
+ }
+
+ if (response_pubkey != NULL) {
+ if (cert_valid.response_sig != NULL) {
+ *response_pubkey = cert->response_sig->pubkey;
+ }
+ }
+
return ERR_OK;
}
diff --git a/src/lq/cert.h b/src/lq/cert.h
@@ -119,10 +119,14 @@ int lq_certificate_deserialize(LQCert **cert, LQResolve *resolve, char *in, size
*
* Messages must have public key set.
*
+ * The public key pointers in the output parameters are valid until the certificate is freed.
+ *
* \param[in] Certificate to verify
+ * \param[out] If not NULL, provides location to store pointer to request publickey. If certificate does not contain a valid request, this will be set to NULL.
+ * \param[out] If not NULL, provider location to store pointer to response publickey. If certificate does not contain a valid response, this will be set to NULL.
* \return ERR_OK if verified, ERR_NOOP if no message.
*/
-int lq_certificate_verify(LQCert *cert);
+int lq_certificate_verify(LQCert *cert, LQPubKey **request_pubkey, LQPubKey **response_pubkey);
/***
diff --git a/src/lq/trust.c b/src/lq/trust.c
@@ -24,7 +24,8 @@ int lq_trust_check(LQPubKey *pubkey, LQStore *store, enum trust_mode_e mode, con
l = (int)((LQ_TRUST_FLAG_BITS - 1)/8+1);
//r = store->get(LQ_CONTENT_KEY, store, pubkey->lokey, pubkey->lolen, key_flags, &l);
keylen = lq_publickey_bytes(pubkey, &keydata);
- r = store->get(LQ_CONTENT_KEY, store, keydata, keylen, (char*)key_flags, &l);
+ //r = store->get(LQ_CONTENT_KEY, store, keydata, keylen, (char*)key_flags, &l);
+ r = store->get(LQ_CONTENT_KEY_PUBLIC, store, keydata, keylen, (char*)key_flags, &l);
if (r != ERR_OK) {
return -1;
}
diff --git a/src/test/Makefile b/src/test/Makefile
@@ -23,7 +23,8 @@ all-tests:
CK_FORK=no LD_LIBRARY_PATH=`realpath ../aux/lib` ./test_query_bin
one-test: build
- CK_FORK=no LD_LIBRARY_PATH=`realpath ../aux/lib` ./test_query_bin
+ CK_FORK=no LD_LIBRARY_PATH=`realpath ../aux/lib` ./test_cert_bin
+ #CK_FORK=no LD_LIBRARY_PATH=`realpath ../aux/lib` ./test_query_bin
test: all
diff --git a/src/test/test_cert.c b/src/test/test_cert.c
@@ -49,7 +49,7 @@ START_TEST(check_cert_sig_req) {
r = lq_certificate_request(cert, req, pk);
ck_assert_int_eq(r, 0);
- r = lq_certificate_verify(cert);
+ r = lq_certificate_verify(cert, NULL, NULL);
ck_assert_int_eq(r, 0);
lq_certificate_free(cert);
@@ -88,7 +88,7 @@ START_TEST(check_cert_sig_res) {
r = lq_certificate_respond(cert, res, pk_bob);
ck_assert_int_eq(r, 0);
- r = lq_certificate_verify(cert);
+ r = lq_certificate_verify(cert, NULL, NULL);
ck_assert_int_eq(r, 0);
lq_certificate_free(cert);
@@ -208,6 +208,7 @@ START_TEST(check_cert_symmetric_ser_rsp_onesig) {
r = lq_certificate_deserialize(&cert, NULL, buf, c);
ck_assert_int_eq(r, 0);
+
r = lq_certificate_respond(cert, res, pk);
ck_assert_int_eq(r, 0);
@@ -257,6 +258,128 @@ START_TEST(check_cert_symmetric_ser_rsp_bothsig) {
lq_certificate_free(cert);
}
END_TEST
+
+START_TEST(check_cert_verify_deserialize_literal) {
+ int r;
+ size_t c;
+ LQCert *cert;
+ LQMsg *req;
+ LQMsg *res;
+ LQPrivKey *pk_alice;
+ LQPrivKey *pk_bob;
+ char buf[LQ_BLOCKSIZE];
+
+ pk_alice = lq_privatekey_new(passphrase, sizeof(passphrase));
+ ck_assert_ptr_nonnull(pk_alice);
+ pk_bob = lq_privatekey_new(passphrase, sizeof(passphrase));
+ ck_assert_ptr_nonnull(pk_bob);
+ r = lq_privatekey_unlock(pk_alice, passphrase, sizeof(passphrase));
+ ck_assert_int_eq(r, 0);
+ r = lq_privatekey_unlock(pk_bob, passphrase, sizeof(passphrase));
+ ck_assert_int_eq(r, 0);
+ cert = lq_certificate_new(NULL);
+ ck_assert_ptr_nonnull(cert);
+
+ req = lq_msg_new(data, strlen(data) + 1);
+ ck_assert_ptr_nonnull(req);
+ lq_msg_literal(req);
+ r = lq_certificate_request(cert, req, pk_alice);
+ ck_assert_int_eq(r, 0);
+
+ res = lq_msg_new(data_two, strlen(data_two) + 1);
+ ck_assert_ptr_nonnull(res);
+ lq_msg_literal(res);
+ r = lq_certificate_respond(cert, res, pk_bob);
+ ck_assert_int_eq(r, 0);
+
+ 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, c);
+ ck_assert_int_eq(r, 0);
+
+ r = lq_certificate_verify(cert, NULL, NULL);
+ ck_assert_int_eq(r, 0);
+
+ lq_certificate_free(cert);
+}
+END_TEST
+
+START_TEST(check_cert_verify_deserialize_literal_with_publickeys) {
+ int r;
+ size_t c;
+ LQCert *cert;
+ LQMsg *req;
+ LQMsg *res;
+ LQPrivKey *pk_alice;
+ LQPrivKey *pk_bob;
+ LQPubKey *pubk_alice;
+ LQPubKey *pubk_bob;
+ LQPubKey *pubk_request;
+ LQPubKey *pubk_response;
+ char buf[LQ_BLOCKSIZE];
+
+ pk_alice = lq_privatekey_new(passphrase, sizeof(passphrase));
+ ck_assert_ptr_nonnull(pk_alice);
+ pk_bob = lq_privatekey_new(passphrase, sizeof(passphrase));
+ ck_assert_ptr_nonnull(pk_bob);
+ r = lq_privatekey_unlock(pk_alice, passphrase, sizeof(passphrase));
+ ck_assert_int_eq(r, 0);
+ r = lq_privatekey_unlock(pk_bob, passphrase, sizeof(passphrase));
+ ck_assert_int_eq(r, 0);
+ cert = lq_certificate_new(NULL);
+ ck_assert_ptr_nonnull(cert);
+
+ req = lq_msg_new(data, strlen(data) + 1);
+ ck_assert_ptr_nonnull(req);
+ lq_msg_literal(req);
+ r = lq_certificate_request(cert, req, pk_alice);
+ ck_assert_int_eq(r, 0);
+
+ res = lq_msg_new(data_two, strlen(data_two) + 1);
+ ck_assert_ptr_nonnull(res);
+ lq_msg_literal(res);
+ r = lq_certificate_respond(cert, res, pk_bob);
+ ck_assert_int_eq(r, 0);
+
+ 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, c);
+ ck_assert_int_eq(r, 0);
+
+ pubk_alice = lq_publickey_from_privatekey(pk_alice);
+ ck_assert_ptr_nonnull(pubk_alice);
+ pubk_bob = lq_publickey_from_privatekey(pk_bob);
+ ck_assert_ptr_nonnull(pubk_bob);
+
+ r = lq_certificate_verify(cert, &pubk_request, NULL);
+ ck_assert_int_eq(r, 0);
+ r = lq_publickey_match(pubk_alice, pubk_request);
+ ck_assert_int_eq(r, 0);
+
+ r = lq_certificate_verify(cert, NULL, &pubk_response);
+ ck_assert_int_eq(r, 0);
+ r = lq_publickey_match(pubk_bob, pubk_response);
+ ck_assert_int_eq(r, 0);
+
+ r = lq_certificate_verify(cert, &pubk_request, &pubk_response);
+ ck_assert_int_eq(r, 0);
+ r = lq_publickey_match(pubk_alice, pubk_request);
+ ck_assert_int_eq(r, 0);
+ r = lq_publickey_match(pubk_bob, pubk_response);
+ ck_assert_int_eq(r, 0);
+
+ lq_publickey_free(pubk_bob);
+ lq_publickey_free(pubk_alice);
+ lq_certificate_free(cert);
+
+}
+END_TEST
//
//START_TEST(check_cert_attach) {
// int r;
@@ -297,6 +420,8 @@ 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_verify_deserialize_literal);
+ tcase_add_test(tc, check_cert_verify_deserialize_literal_with_publickeys);
// tcase_add_test(tc, check_cert_attach);
suite_add_tcase(s, tc);
diff --git a/src/test/test_trust.c b/src/test/test_trust.c
@@ -63,7 +63,7 @@ START_TEST(check_trust_none) {
pubkey_bob = lq_publickey_new(pubkey_data_bob);
lolen = lq_publickey_bytes(pubkey_alice, &lodata);
- store->put(LQ_CONTENT_KEY, store, lodata, &lolen, (char*)trust_alice, 2);
+ store->put(LQ_CONTENT_KEY_PUBLIC, store, lodata, &lolen, (char*)trust_alice, 2);
lq_set(flag_test, 0, 2);
r = lq_trust_check(pubkey_alice, store, TRUST_MATCH_NONE, flag_test);
@@ -73,7 +73,7 @@ START_TEST(check_trust_none) {
ck_assert_int_eq(r, -1);
lolen = lq_publickey_bytes(pubkey_bob, &lodata);
- store->put(LQ_CONTENT_KEY, store, lodata, &lolen, (char*)trust_bob, 2);
+ store->put(LQ_CONTENT_KEY_PUBLIC, store, lodata, &lolen, (char*)trust_bob, 2);
r = lq_trust_check(pubkey_bob, store, TRUST_MATCH_NONE, flag_test);
ck_assert_int_eq(r, 1000000);
@@ -101,7 +101,7 @@ START_TEST(check_trust_one) {
pubkey_alice = lq_publickey_new(pubkey_data_alice);
lolen = lq_publickey_bytes(pubkey_alice, &lodata);
- store->put(LQ_CONTENT_KEY, store, lodata, &lolen, (char*)trust_alice, 2);
+ store->put(LQ_CONTENT_KEY_PUBLIC, store, lodata, &lolen, (char*)trust_alice, 2);
flag_test[0] = 0;
flag_test[1] = 0x40;
@@ -132,7 +132,7 @@ START_TEST(check_trust_best) {
pubkey_alice = lq_publickey_new(pubkey_data_alice);
lolen = lq_publickey_bytes(pubkey_alice, &lodata);
- store->put(LQ_CONTENT_KEY, store, lodata, &lolen, (char*)trust_alice, 2);
+ store->put(LQ_CONTENT_KEY_PUBLIC, store, lodata, &lolen, (char*)trust_alice, 2);
flag_test[0] = 0x13;
flag_test[1] = 0x60;
@@ -163,7 +163,7 @@ START_TEST(check_trust_all) {
pubkey_alice = lq_publickey_new(pubkey_data_alice);
lolen = lq_publickey_bytes(pubkey_alice, &lodata);
- store->put(LQ_CONTENT_KEY, store, lodata, &lolen, (char*)trust_alice, 2);
+ store->put(LQ_CONTENT_KEY_PUBLIC, store, lodata, &lolen, (char*)trust_alice, 2);
flag_test[0] = 0x13;
flag_test[1] = 0x60;