libqaeda

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

commit 0fc8e29aafecb14d8bfee0b46ac51cc796315ffe
parent 5b0094b198b47ad7512fdb1013ac712edb3ecaea
Author: lash <dev@holbrook.no>
Date:   Sun,  2 Mar 2025 18:19:09 +0000

Add request signature to response signature material

Diffstat:
Msrc/crypto/dummy.c | 14++++++++------
Msrc/lq/cert.c | 26++++++++++++++++++++++++--
Msrc/lq/crypto.h | 5++---
Msrc/lq/msg.c | 24+++++++++++++++---------
Msrc/lq/msg.h | 8++++++--
Msrc/test/test_crypto.c | 2+-
6 files changed, 56 insertions(+), 23 deletions(-)

diff --git a/src/crypto/dummy.c b/src/crypto/dummy.c @@ -77,7 +77,7 @@ LQPubKey* lq_publickey_from_privatekey(LQPrivKey *pk) { return pubk; } -LQSig* lq_privatekey_sign(LQPrivKey *pk, const char *msg, size_t msg_len, const char *salt, size_t salt_len) { +LQSig* lq_privatekey_sign(LQPrivKey *pk, const char *msg, size_t msg_len, const char *salt) { int i; const char *src; char *dst; @@ -86,9 +86,6 @@ LQSig* lq_privatekey_sign(LQPrivKey *pk, const char *msg, size_t msg_len, const if (msg_len != LQ_DIGEST_LEN) { return NULL; } - if (salt_len != LQ_SALT_LEN) { - return NULL; - } sig = lq_alloc(sizeof(LQSig)); sig->pubkey = lq_publickey_from_privatekey(pk); @@ -99,13 +96,18 @@ LQSig* lq_privatekey_sign(LQPrivKey *pk, const char *msg, size_t msg_len, const src = msg + i; dst = sig->losig + i; *dst = *src ^ sig_dummy_transform[i]; - *dst ^= *(salt + i); + if (salt != NULL) { + *dst ^= *(salt + (i % LQ_SALT_LEN)); + } src += msg_len; dst += msg_len; *dst = *src ^ sig_dummy_transform[i + msg_len]; - *dst ^= *(salt + i); + if (salt != NULL) { + *dst ^= *(salt + (i % LQ_SALT_LEN)); + } } + *(((char*)sig->losig) + sig->lolen) = 0x2a; return sig; diff --git a/src/lq/cert.c b/src/lq/cert.c @@ -54,7 +54,29 @@ void lq_certificate_set_domain(LQCert *cert, const char *domain) { lq_cpy(cert->domain, domain, LQ_CERT_DOMAIN_LEN); } +static int state_digest(LQCert *cert, char *out) { + int c; + char data[1024]; + char *p; + + c = LQ_CERT_DOMAIN_LEN; + p = data; + lq_cpy(p, cert->domain, c); + p += c; + + if (cert->request_sig != NULL) { + lq_cpy(p, cert->request_sig->losig, cert->request_sig->lolen); + c += cert->request_sig->lolen; + p += cert->request_sig->lolen; + } + + return lq_digest(data, c, out); +} + int lq_certificate_sign(LQCert *cert, LQPrivKey *pk) { + char out[LQ_DIGEST_LEN]; + + state_digest(cert, out); if (cert->response != NULL) { if (cert->response_sig != NULL) { return ERR_RESPONSE; @@ -62,7 +84,7 @@ int lq_certificate_sign(LQCert *cert, LQPrivKey *pk) { if (cert->request == NULL) { return ERR_INIT; } - cert->response_sig = lq_msg_sign(cert->response, pk); + cert->response_sig = lq_msg_sign_extra(cert->response, pk, NULL, out, LQ_DIGEST_LEN); if (cert->response_sig == NULL) { return ERR_ENCODING; } @@ -74,7 +96,7 @@ int lq_certificate_sign(LQCert *cert, LQPrivKey *pk) { if (cert->request_sig != NULL) { return ERR_REQUEST; } - cert->request_sig = lq_msg_sign(cert->request, pk); + cert->request_sig = lq_msg_sign_extra(cert->request, pk, NULL, out, LQ_DIGEST_LEN); if (cert->request_sig == NULL) { return ERR_ENCODING; } diff --git a/src/lq/crypto.h b/src/lq/crypto.h @@ -109,12 +109,11 @@ LQPubKey* lq_publickey_from_privatekey(LQPrivKey *pk); * @param[in] Unencrypted private key to use for the signature. * @param[in] Message digest to sign. * @param[in] Length of message to sign. - * @param[in] Salt data to use for the signature. - * @param[in] Length of salt data. + * @param[in] Salt data to use for the signature. Set to NULL if salt is not to be used. If not null, must be LQ_SALT_LEN long. * @return Signature object if signing was successful. Returns NULL if signature failed. * @see lq_signature_free */ -LQSig* lq_privatekey_sign(LQPrivKey *pk, const char *msg, size_t msg_len, const char *salt, size_t salt_len); +LQSig* lq_privatekey_sign(LQPrivKey *pk, const char *msg, size_t msg_len, const char *salt); /*** diff --git a/src/lq/msg.c b/src/lq/msg.c @@ -15,8 +15,6 @@ static LQPubKey nokey = { .lolen = 0, }; -static char nosalt[LQ_SALT_LEN]; - LQMsg* lq_msg_new(const char *msg_data, size_t msg_len) { LQMsg *msg; @@ -31,25 +29,33 @@ LQMsg* lq_msg_new(const char *msg_data, size_t msg_len) { return msg; } -LQSig* lq_msg_sign(LQMsg *msg, LQPrivKey *pk) { - return lq_msg_sign_salted(msg, pk, nosalt); +LQSig* lq_msg_sign(LQMsg *msg, LQPrivKey *pk, const char *salt) { + return lq_msg_sign_extra(msg, pk, salt, NULL, 0); } -LQSig* lq_msg_sign_salted(LQMsg *msg, LQPrivKey *pk, const char *salt) { +LQSig* lq_msg_sign_extra(LQMsg *msg, LQPrivKey *pk, const char *salt, const char *extra, size_t extra_len) { + int l; int r; char *data; char digest[LQ_DIGEST_LEN]; LQSig *sig; - data = lq_alloc(msg->len); - lq_cpy(data, msg->data, msg->len); + if (extra == NULL) { + extra_len = 0; + } + l = msg->len + extra_len; + data = lq_alloc(l); + if (extra_len > 0) { + lq_cpy(data, extra, extra_len); + } + lq_cpy(data + extra_len, msg->data, msg->len); msg->pubkey = lq_publickey_from_privatekey(pk); - r = lq_digest(data, msg->len, (char*)digest); + r = lq_digest(data, l, (char*)digest); if (r != ERR_OK) { return NULL; } - sig = lq_privatekey_sign(pk, digest, LQ_DIGEST_LEN, salt, LQ_SALT_LEN); + sig = lq_privatekey_sign(pk, digest, LQ_DIGEST_LEN, salt); return sig; } diff --git a/src/lq/msg.h b/src/lq/msg.h @@ -39,19 +39,23 @@ LQMsg* lq_msg_new(const char *msg_data, size_t msg_len); * @brief Calculate a signature over the message. Uses default salt value. * @param[in] Message to sign. * @param[in] Private key to sign with. + * @param[in] Salt data to secure signature with. Set to NULL if salt is not to be used. * @return Signature object. Object will be NULL if signature calculation failed. It is the caller's responsibility to free the signature object. * @see lq_signature_free */ -LQSig* lq_msg_sign(LQMsg *msg, LQPrivKey *pk); +LQSig* lq_msg_sign(LQMsg *msg, LQPrivKey *pk, const char *salt); /*** * @brief Calculate a signature over the message with a specified salt value. The salt value length must be LQ_SALT_LEN. * @param[in] Message to sign. * @param[in] Private key to sign with. + * @param[in] Salt data to secure signature with. Set to NULL if salt is not to be used. + * @param[in] Extra data to prefix message data with when calculating digest. If set to NULL, only message data will be used in digest. + * @param[in] Length of extra data. Ignored if extra data is NULL. * @return Signature object. Object will be NULL if signature calculation failed. It is the caller's responsibility to free the signature object. * @see lq_signature_free */ -LQSig* lq_msg_sign_salted(LQMsg *msg, LQPrivKey *pk, const char *salt); +LQSig* lq_msg_sign_extra(LQMsg *msg, LQPrivKey *pk, const char *salt, const char *extra, size_t extra_len); /*** * @brief Serialize message data payload for inclusion in certificate. diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c @@ -40,7 +40,7 @@ START_TEST(check_signature) { pk = lq_privatekey_new(data, 32); lq_digest(data, strlen(data), (char*)digest); - sig = lq_privatekey_sign(pk, digest, 32, salt, 32); + sig = lq_privatekey_sign(pk, digest, 32, salt); r = 42; ck_assert_mem_eq((sig->losig)+65, &r, 1);