commit 45b14652b85df87df952311cd324b37ffc67d094
parent 8af665c5171e1483342a8873bed864aaf9cd7f09
Author: lash <dev@holbrook.no>
Date: Fri, 28 Mar 2025 01:56:48 +0000
Implement private key load
Diffstat:
5 files changed, 69 insertions(+), 20 deletions(-)
diff --git a/src/crypto/gcrypt.c b/src/crypto/gcrypt.c
@@ -32,9 +32,10 @@ char *_rerr[7] = {
};
#endif
+/// Lookup mode for key in store.
enum gpg_find_mode_e {
- GPG_FIND_MAIN,
- GPG_FIND_FINGERPRINT,
+ GPG_FIND_MAIN, ///< Use default key filename.
+ GPG_FIND_FINGERPRINT, ///<
};
/**
@@ -67,10 +68,11 @@ static int gpg_passphrase_digest_len;
* Verifies that installed gpg version is supported.
* Sets up crypto keys dir and sets passphrase digest length.
*/
-int lq_crypto_init() {
+int lq_crypto_init(const char *base) {
#ifdef RERR
rerr_register(RERR_PFX_GPG, "crypto", _rerr);
#endif
+ int r;
const char *v;
if (gpg_version == NULL) {
@@ -84,6 +86,10 @@ int lq_crypto_init() {
gpg_passphrase_digest_len = gcry_md_get_algo_dlen(GCRY_MD_SHA256);
gpg_cfg_idx_dir = lq_config_register(LQ_TYP_STR, "CRYPTODIR");
+ r = lq_config_set(gpg_cfg_idx_dir, base);
+ if (r) {
+ return ERR_FAIL;
+ }
// strcpy(gpg->path, path);
// c = strlen(gpg->path);
@@ -492,10 +498,11 @@ LQPrivKey* lq_privatekey_load(const char *passphrase, size_t passphrase_len) {
return NULL;
}
- r = lq_config_get(LQ_TYP_STR, (void**)&p);
+ r = lq_config_get(gpg_cfg_idx_dir, (void**)&p);
if (r) {
return NULL;
}
+
gpg = lq_alloc(sizeof(struct gpg_store));
store = lq_store_new(p);
if (store == NULL) {
@@ -506,8 +513,12 @@ LQPrivKey* lq_privatekey_load(const char *passphrase, size_t passphrase_len) {
if (r) {
return NULL;
}
+ pk = lq_alloc(sizeof(LQPrivKey));
+ pk->key_typ = GPG_KEY_TYP;
+ pk->key_state = LQ_KEY_INIT;
+ pk->impl = gpg;
- return NULL;
+ return pk;
}
size_t lq_publickey_bytes(LQPubKey *pubk, char **out) {
diff --git a/src/lq/crypto.h b/src/lq/crypto.h
@@ -103,7 +103,7 @@ typedef struct lq_signature_t LQSig;
*
* \return ERR_OK on success.
*/
-int lq_crypto_init();
+int lq_crypto_init(const char *base);
/**
* \brief Perform necessary resource release of crypto component.
@@ -125,6 +125,18 @@ void lq_crypto_free();
LQPrivKey* lq_privatekey_new(const char *seed, size_t seed_len, const char *passphrase, size_t passphrase_len);
/**
+ * \brief Load a private key from store.
+ *
+ * If passphrase is not null the passphrase will be encrypted using that passphrase by default.
+ *
+ * \param[in] Passphrase to encrypt key with. If NULL, key will be encrypted with a single 0-byte as passphrase.
+ * \param[in] Passphrase length. Ignored if passphrase is NULL.
+ * \return Pointer to new private key. Freeing the object is the caller's responsibility.
+ * \see lq_privatekey_free
+ */
+
+LQPrivKey* lq_privatekey_load(const char *passphrase, size_t passphrase_len);
+/**
* \brief Get raw private key bytes
*
* \param[in] Private key object.
diff --git a/src/test/test_cert.c b/src/test/test_cert.c
@@ -166,7 +166,7 @@ Suite * common_suite(void) {
TCase *tc;
lq_config_init();
- lq_crypto_init();
+ lq_crypto_init("./testdata");
s = suite_create("cert");
tc = tcase_create("serialize");
diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c
@@ -18,13 +18,21 @@ static const char privkeydata[32] = {
};
// sha256sum "bar" fcde2b2edba56bf408601fb721fe9b5c338d10ee429ea04fae5511b68fbf8fb9
-static const char passphrase[32] = {
- 0xfc, 0xde, 0x2b, 0x2e, 0xdb, 0xa5, 0x6b, 0xf4,
- 0x08, 0x60, 0x1f, 0xb7, 0x21, 0xfe, 0x9b, 0x5c,
- 0x33, 0x8d, 0x10, 0xee, 0x42, 0x9e, 0xa0, 0x4f,
- 0xae, 0x55, 0x11, 0xb6, 0x8f, 0xbf, 0x8f, 0xb9,
+//static const char passphrase[32] = {
+// 0xfc, 0xde, 0x2b, 0x2e, 0xdb, 0xa5, 0x6b, 0xf4,
+// 0x08, 0x60, 0x1f, 0xb7, 0x21, 0xfe, 0x9b, 0x5c,
+// 0x33, 0x8d, 0x10, 0xee, 0x42, 0x9e, 0xa0, 0x4f,
+// 0xae, 0x55, 0x11, 0xb6, 0x8f, 0xbf, 0x8f, 0xb9,
+//};
+
+
+// "1234"
+static const size_t passphrase_len = 4;
+static const char passphrase[4] = {
+ 0x31, 0x32, 0x33, 0x34,
};
+
struct dummycrypto {
void *data; ///< Literal private key data.
size_t len; ///< Length of private key data.
@@ -43,11 +51,6 @@ START_TEST(check_privatekey) {
int r;
LQPrivKey *pk;
- r = lq_config_init();
- ck_assert_int_eq(r, 0);
-
- r = lq_crypto_init();
- ck_assert_int_eq(r, 0);
pk = lq_privatekey_new(privkeydata, LQ_PRIVKEY_LEN, NULL, 0);
ck_assert_ptr_nonnull(pk);
@@ -62,7 +65,7 @@ START_TEST(check_publickey) {
char *keydata;
char *keydata_manual;
- pk = lq_privatekey_new(privkeydata, LQ_PRIVKEY_LEN, passphrase, 32);
+ pk = lq_privatekey_new(privkeydata, LQ_PRIVKEY_LEN, passphrase, passphrase_len);
pubk = lq_publickey_from_privatekey(pk);
lq_publickey_bytes(pubk, &keydata);
pubk_manual = lq_publickey_new(keydata);
@@ -81,7 +84,7 @@ START_TEST(check_signature) {
LQSig *sig;
char *sigdata;
- pk = lq_privatekey_new(privkeydata, 32, passphrase, 32);
+ pk = lq_privatekey_new(privkeydata, 32, passphrase, passphrase_len);
sig = lq_privatekey_sign(pk, data, strlen(data), salt);
ck_assert_ptr_null(sig);
@@ -122,28 +125,51 @@ START_TEST(check_verify) {
}
END_TEST
+START_TEST(check_load) {
+ LQPrivKey *pk;
+
+ pk = lq_privatekey_load(passphrase, passphrase_len);
+ ck_assert_ptr_nonnull(pk);
+
+ lq_privatekey_free(pk);
+}
+END_TEST
+
Suite * common_suite(void) {
+ int r;
Suite *s;
TCase *tc;
s = suite_create("crypto");
- tc = tcase_create("dummy");
+ tc = tcase_create("file");
tcase_add_test(tc, check_digest);
tcase_add_test(tc, check_privatekey);
tcase_add_test(tc, check_publickey);
tcase_add_test(tc, check_signature);
tcase_add_test(tc, check_verify);
+ tcase_add_test(tc, check_load);
suite_add_tcase(s, tc);
return s;
}
int main(void) {
+ int r;
int n_fail;
Suite *s;
SRunner *sr;
+ r = lq_config_init();
+ if (r) {
+ return 1;
+ }
+
+ r = lq_crypto_init("./testdata/");
+ if (r) {
+ return 1;
+ }
+
s = common_suite();
sr = srunner_create(s);
diff --git a/src/test/testdata/lq.gpg b/src/test/testdata/lq.gpg
Binary files differ.