commit f0e15c95a339726d2f4dfdca54fb2c04a846ee85
parent 06367d473ea3d86800bacb605d488701570441f0
Author: lash <dev@holbrook.no>
Date: Fri, 5 Apr 2024 08:57:34 +0100
Implement gpg store and key unlocking
Diffstat:
14 files changed, 601 insertions(+), 105 deletions(-)
diff --git a/src/context.c b/src/context.c
@@ -1,22 +0,0 @@
-#include <string.h>
-
-#include "context.h"
-#include "settings.h"
-#include "camera.h"
-#include "err.h"
-
-
-int kee_context_new(struct kee_context *ctx, struct kee_settings *settings) {
- memset(ctx, 0, sizeof(struct kee_context));
- ctx->state = 1;
- ctx->settings = settings;
-
- return ERR_OK;
-}
-
-int kee_context_state(struct kee_context *ctx) {
- return ctx->state;
-}
-
-void kee_context_free(struct kee_context *ctx) {
-}
diff --git a/src/context.h b/src/context.h
@@ -1,20 +0,0 @@
-#ifndef _KEE_CONTEXT
-#define _KEE_CONTEXT
-
-#include "settings.h"
-#include "db.h"
-#include "camera.h"
-
-struct kee_context {
- void *front;
- struct kee_settings *settings;
- struct kee_camera_devices camera_devices;
- struct db_ctx db;
- int state;
-};
-
-int kee_context_new(struct kee_context *ctx, struct kee_settings *settings);
-int kee_context_state(struct kee_context *ctx);
-void kee_context_free(struct kee_context *ctx);
-
-#endif // _KEE_CONTEXT
diff --git a/src/err.h b/src/err.h
@@ -21,7 +21,12 @@ enum keeError {
ERR_INPUT_DUP,
/// Last input changes entry that already exists in storage, but was not allowed
ERR_INPUT_PROTECT,
-
+ /// Crypto backend unavailable
+ ERR_NOCRYPTO,
+ /// Crypto resource fail
+ ERR_NOKEY,
+ /// Crypto authentication fail
+ ERR_KEYFAIL,
};
#endif // _KEE_ERR_H
diff --git a/src/gpg.c b/src/gpg.c
@@ -0,0 +1,395 @@
+#include <gcrypt.h>
+#include <string.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <errno.h>
+
+#include "err.h"
+#include "debug.h"
+#include "gpg.h"
+#include "hex.h"
+#include "digest.h"
+
+#define BUFLEN 1024 * 1024
+
+
+//const char *gpgVersion = nullptr;
+const char *gpgVersion = NULL;
+
+
+size_t get_padsize(size_t insize, size_t blocksize) {
+ size_t c;
+ size_t l;
+ size_t m;
+
+ c = insize + 1;
+ l = c / blocksize;
+ m = c % blocksize;
+ if (m) {
+ l++;
+ }
+ return l * blocksize;
+}
+
+static void padb(char *data, size_t outsize, size_t insize) {
+ gcry_randomize(data + insize, outsize - insize, GCRY_STRONG_RANDOM);
+}
+
+//void pad(char *indata_raw, size_t outsize, std::string indata) {
+static void pad(char *indata_raw, size_t outsize, const char *indata) { //std::string indata) {
+ int l;
+
+ //strcpy(indata_raw, indata.c_str());
+ strcpy(indata_raw, indata);
+ //l = indata.length() + 1;
+ l = strlen(indata) + 1;
+ padb(indata_raw, outsize, l);
+}
+
+static int create_handle(gcry_cipher_hd_t *h, const char *key, const char *nonce) {
+ gcry_error_t e;
+
+ e = gcry_cipher_open(h, GCRY_CIPHER_CHACHA20, GCRY_CIPHER_MODE_POLY1305, GCRY_CIPHER_SECURE);
+ if (e) {
+ return ERR_NOCRYPTO;
+ }
+ e = gcry_cipher_setkey(*h, key, CHACHA20_KEY_LENGTH_BYTES);
+ if (e) {
+ return ERR_NOCRYPTO;
+ }
+ e = gcry_cipher_setiv(*h, nonce, CHACHA20_NONCE_LENGTH_BYTES);
+ if (e) {
+ return ERR_NOCRYPTO;
+ }
+ return ERR_OK;
+}
+
+
+static void free_handle(gcry_cipher_hd_t *h) {
+ gcry_cipher_close(*h);
+}
+
+int encryptb (char *ciphertext, size_t ciphertext_len, const char *indata, size_t indata_len, const char *key, const char *nonce) {
+ int r;
+ gcry_cipher_hd_t h;
+ gcry_error_t e;
+ char indata_raw[ciphertext_len];
+
+ r = create_handle(&h, key, nonce);
+ if (r) {
+ return r;
+ }
+ memcpy(indata_raw, indata, indata_len);
+ padb(indata_raw, ciphertext_len, indata_len);
+ e = gcry_cipher_encrypt(h, (unsigned char*)ciphertext, ciphertext_len, (const unsigned char*)indata_raw, ciphertext_len);
+ if (e) {
+ return ERR_NOCRYPTO;
+ }
+
+ free_handle(&h);
+
+ return ERR_OK;
+}
+
+//int encrypt(char *ciphertext, size_t ciphertext_len, std::string indata, const char *key, const char *nonce) {
+int encrypt(char *ciphertext, size_t ciphertext_len, const char *indata, const char *key, const char *nonce) {
+ int r;
+ gcry_cipher_hd_t h;
+ gcry_error_t e;
+ char indata_raw[ciphertext_len];
+
+ r = create_handle(&h, key, nonce);
+ if (r) {
+ return r;
+ }
+
+ pad(indata_raw, ciphertext_len, indata);
+ e = gcry_cipher_encrypt(h, (unsigned char*)ciphertext, ciphertext_len, (const unsigned char*)indata_raw, ciphertext_len);
+ if (e) {
+ return ERR_NOCRYPTO;
+ }
+
+ free_handle(&h);
+
+ return ERR_OK;
+}
+
+int decryptb(char *outdata, const char *ciphertext, size_t ciphertext_len, const char *key, const char *nonce) {
+ int r;
+ gcry_cipher_hd_t h;
+ gcry_error_t e;
+
+ r = create_handle(&h, key, nonce);
+ if (r) {
+ return r;
+ }
+
+ e = gcry_cipher_decrypt(h, outdata, ciphertext_len, ciphertext, ciphertext_len);
+ if (e) {
+ return ERR_NOCRYPTO;
+ }
+
+ free_handle(&h);
+
+ return ERR_OK;
+
+}
+
+//int decrypt(std::string *outdata, const char *ciphertext, size_t ciphertext_len, const char *key, const char *nonce) {
+int decrypt(char *outdata, const char *ciphertext, size_t ciphertext_len, const char *key, const char *nonce) {
+ int r;
+ gcry_cipher_hd_t h;
+ gcry_error_t e;
+ char outdata_raw[ciphertext_len] = {};
+
+ outdata_raw[0] = 0;
+ r = create_handle(&h, key, nonce);
+ if (r) {
+ return r;
+ }
+
+ e = gcry_cipher_decrypt(h, outdata_raw, ciphertext_len, ciphertext, ciphertext_len);
+ if (e) {
+ return ERR_NOCRYPTO;
+ }
+ //outdata->assign(outdata_raw);
+ strcpy(outdata, outdata_raw);
+
+ free_handle(&h);
+
+ return ERR_OK;
+}
+
+static int key_from_data(gcry_sexp_t *key, const char *indata, size_t indata_len) {
+ gcry_error_t e;
+
+ e = gcry_sexp_new(key, indata, indata_len, 1);
+ if (e != GPG_ERR_NO_ERROR) {
+ //debug_log(DEBUG_DEBUG, indata);
+ return ERR_KEYFAIL;
+ }
+ return ERR_OK;
+}
+
+static int key_from_path(gcry_sexp_t *key, const char *p, const char *passphrase) {
+ int l;
+ int r;
+ char v[BUFLEN];
+ size_t c;
+ size_t i;
+ FILE *f;
+ char *fullpath;
+ char nonce[CHACHA20_NONCE_LENGTH_BYTES];
+ void *outdata;
+
+ fullpath = (char*)malloc(strlen(p) + 8);
+ sprintf(fullpath, "%s/%s", p, "key.bin");
+
+ f = fopen(fullpath, "r");
+ if (f == NULL) {
+ return ERR_NOKEY;
+ }
+ free(fullpath);
+
+ c = fread(&l, sizeof(int), 1, f);
+ c = fread(nonce, CHACHA20_NONCE_LENGTH_BYTES, 1, f);
+ i = 0;
+ c = 1;
+ while (c != 0 && i < BUFLEN) {
+ c = fread(v+i, 1024, 1, f);
+ c *= 1024;
+ i += c;
+ }
+ if (i == 0) {
+ return ERR_NOKEY;
+ }
+ fclose(f);
+
+ outdata = malloc(i);
+ r = decryptb((char*)outdata, v, i, passphrase, nonce);
+ if (r) {
+ return ERR_NOKEY;
+ }
+ r = key_from_data(key, (char*)outdata, l);
+ free(outdata);
+ return r;
+}
+
+/**
+ * \todo consistent endianness for key length in persistent storage (fwrite)
+ */
+static int key_create(gcry_sexp_t *key, const char *p, const char *passphrase) {
+ int r;
+ FILE *f;
+ const char *sexp_quick = "(genkey(ecc(curve Ed25519)))";
+ //char *pv;
+ int i;
+ int l;
+ int kl;
+ size_t c;
+ gcry_sexp_t in;
+ gcry_error_t e;
+ char v[BUFLEN];
+ char nonce[CHACHA20_NONCE_LENGTH_BYTES];
+
+
+ e = gcry_sexp_new(&in, (const void*)sexp_quick, strlen(sexp_quick), 0);
+ if (e) {
+ printf("error sexp: %s\n", gcry_strerror(e));
+ return (int)e;
+ }
+ e = gcry_pk_genkey(key, in);
+ if (e) {
+ printf("error gen: %s\n", gcry_strerror(e));
+ return (int)e;
+ }
+ kl = gcry_sexp_sprint(*key, GCRYSEXP_FMT_CANON, v, BUFLEN);
+
+ c = get_padsize(kl, ENCRYPT_BLOCKSIZE);
+ char ciphertext[c];
+
+ gcry_create_nonce(nonce, CHACHA20_NONCE_LENGTH_BYTES);
+ r = encryptb(ciphertext, c, v, kl, passphrase, nonce);
+ if (r) {
+ return ERR_KEYFAIL;
+ }
+
+ f = fopen(p, "w");
+ if (f == NULL) {
+ return ERR_KEYFAIL;
+ }
+ l = c;
+ c = fwrite(&kl, sizeof(int), 1, f);
+ if (c != 1) {
+ fclose(f);
+ return ERR_KEYFAIL;
+ }
+ c = fwrite(nonce, CHACHA20_NONCE_LENGTH_BYTES, 1, f);
+ if (c != 1) {
+ fclose(f);
+ return ERR_KEYFAIL;
+ }
+ i = 0;
+ c = 1;
+ while (c != 0 && l > 0) {
+ c = fwrite(ciphertext+i, 1024, 1, f);
+ c *= 1024;
+ i += c;
+ l -= c;
+ }
+ fclose(f);
+
+ return ERR_OK;
+}
+
+static int sign(gcry_sexp_t *out, gcry_sexp_t *key, const char *v) {
+ gcry_error_t e;
+ gcry_sexp_t data;
+ char in[BUFLEN];
+
+ sprintf(in, "(data(flags eddsa(hash-algo sha512(value %s))))", v);
+ gcry_sexp_new(&data, in, strlen(in), 0);
+ e = gcry_pk_sign(out, data, *key);
+ if (e) {
+ sprintf(in, "error sign: %s\n", gcry_strerror(e));
+ debug_log(DEBUG_ERROR, in);
+ return ERR_KEYFAIL;
+ }
+ return 0;
+}
+
+//char *GpgStore::get_fingerprint() {
+// return m_fingerprint;
+//}
+char *gpg_store_get_fingerprint(struct gpg_store *gpg) {
+ return gpg->fingerprint;
+}
+
+
+//int GpgStore::digest(char *out, std::string in) {
+int gpg_store_digest(struct gpg_store *gpg, char *out, const char *in) {
+ const char *s;
+ size_t l;
+
+ //l = in.length();
+ l = strlen(in);
+ s = in; //.c_str();
+ return calculate_digest(s, l, out); //, m_passphrase_digest_len);
+}
+
+//GpgStore::GpgStore() {
+// m_passphrase_digest_len = gcry_md_get_algo_dlen(GCRY_MD_SHA256);
+//}
+/// \todo handle path length limit
+void gpg_store_init(struct gpg_store *gpg, const char *path) {
+ gpg->passphrase_digest_len = gcry_md_get_algo_dlen(GCRY_MD_SHA256);
+ strcpy(gpg->path, path);
+
+}
+
+//int GpgStore::check(std::string p, std::string passphrase) {
+//int gpg_store_check(struct gpg_store *gpg, const char *p, const char *passphrase) {
+int gpg_store_check(struct gpg_store *gpg, const char *passphrase) {
+ int r;
+ const char *v;
+ char d[1024];
+ gcry_sexp_t k;
+ gcry_sexp_t o;
+ char *p;
+ unsigned char fingerprint[20] = { 0x00 };
+ size_t fingerprint_len = 41;
+ //char passphrase_hash[m_passphrase_digest_len];
+ char passphrase_hash[gpg->passphrase_digest_len];
+
+ p = gpg->path;
+
+ //digest(passphrase_hash, passphrase);
+ gpg_store_digest(gpg, passphrase_hash, passphrase);
+
+ if (gpgVersion == NULL) {
+ v = gcry_check_version(GPG_MIN_VERSION);
+ //if (v == nullptr) {
+ if (v == NULL) {
+ return ERR_NOCRYPTO;
+ }
+ }
+ gpgVersion = v;
+ sprintf(d, "Using gpg version: %s", gpgVersion);
+ debug_log(DEBUG_INFO, d);
+ //r = key_from_path(&k, p.c_str(), passphrase_hash);
+ //r = key_from_path(&k, p, passphrase_hash);
+ r = key_from_path(&k, gpg->path, passphrase_hash);
+ if (r == ERR_KEYFAIL) {
+ char pp[2048];
+ //sprintf(pp, "could not decrypt key in %s/key.bin", p.c_str());
+ sprintf(pp, "could not decrypt key in %s/key.bin", p);
+ debug_log(DEBUG_CRITICAL, pp);
+ return 1;
+ }
+ if (r != ERR_OK) {
+ char pp[2048];
+ //sprintf(pp, "%s/key.bin", p.c_str());
+ sprintf(pp, "%s/key.bin", p);
+ r = key_create(&k, pp, passphrase_hash);
+ if (r != ERR_OK) {
+ return r;
+ }
+ gcry_pk_get_keygrip(k, fingerprint);
+ //bin_to_hex(fingerprint, 20, (unsigned char*)m_fingerprint, &fingerprint_len);
+ bin_to_hex(fingerprint, 20, (unsigned char*)gpg->fingerprint, &fingerprint_len);
+ char ppp[4096];
+ //sprintf(ppp, "created key %s from %s", m_fingerprint, pp);
+ sprintf(ppp, "created key %s from %s", gpg->fingerprint, pp);
+ debug_log(DEBUG_INFO, ppp);
+ } else {
+ gcry_pk_get_keygrip(k, fingerprint);
+ //bin_to_hex(fingerprint, 20, (unsigned char*)m_fingerprint, &fingerprint_len);
+ bin_to_hex(fingerprint, 20, (unsigned char*)gpg->fingerprint, &fingerprint_len);
+ char pp[4096];
+ //sprintf(pp, "found key %s in %s", (unsigned char*)m_fingerprint, p.c_str());
+ sprintf(pp, "found key %s in %s", (unsigned char*)gpg->fingerprint, p);
+ debug_log(DEBUG_INFO, pp);
+ }
+ r = sign(&o, &k, "foo");
+ return r;
+}
diff --git a/src/gpg.h b/src/gpg.h
@@ -1,6 +1,7 @@
#ifndef _KEE_GPG_H
#define _KEE_GPG_H
-#include <string>
+
+//#include <string>
#include <stddef.h>
#define GPG_MIN_VERSION "1.10.2"
@@ -11,6 +12,12 @@
#define ENCRYPT_BLOCKSIZE 4096
#endif
+struct gpg_store {
+ size_t passphrase_digest_len;
+ char fingerprint[40];
+ char path[1024];
+};
+
/**
*
* \brief Encrypt the given string data with the provided encryption key and nonce.
@@ -18,7 +25,8 @@
* \sa encryptb
*
*/
-int encrypt(char *ciphertext, size_t ciphertext_len, std::string indata, const char *key, const char *nonce);
+//int encrypt(char *ciphertext, size_t ciphertext_len, std::string indata, const char *key, const char *nonce);
+int encrypt(char *ciphertext, size_t ciphertext_len, const char *indata, const char *key, const char *nonce);
/**
*
@@ -44,7 +52,8 @@ int encryptb (char *ciphertext, size_t ciphertext_len, const char *indata, size_
* \sa decryptb
*
*/
-int decrypt(std::string *outdata, const char *ciphertext, size_t ciphertext_len, const char *key, const char *nonce);
+//int decrypt(std::string *outdata, const char *ciphertext, size_t ciphertext_len, const char *key, const char *nonce);
+int decrypt(char *outdata, const char *ciphertext, size_t ciphertext_len, const char *key, const char *nonce);
/**
*
@@ -74,44 +83,50 @@ int decryptb(char *outdata, const char *ciphertext, size_t ciphertext_len, const
*/
size_t get_padsize(size_t insize, size_t blocksize);
-/**
- *
- * \brief Interface to the encrypted key storage for both identity public key and the key used for encryption of the identity public key.
- *
- */
-class GpgStore {
- public:
- /// Sets correct context values for underlying \c gcrypt operations.
- GpgStore();
- /**
- *
- * Attempts to decrypt the identity public key with the given passphrase.
- *
- * If no public key exists, one will be created and encrypted using the passphrase.
- *
- * \param p path to key store
- * \param passphrase passphrase for public key encryption
- * \return 0 if successful, any other value indicates an error
- *
- */
- int check(std::string p, std::string passphrase);
- /**
- *
- * Returns the fingerprint of the identity public key.
- *
- * \return 160-bit fingerprint value
- */
- char *get_fingerprint();
-
- private:
- /// calculates sha256 digest for the given string value, using secure memory
- int digest(char *out, std::string in);
- //const char *m_version;
- //char *m_seckey;
- /// cached fingerprint value, in string format with zero terminator
- char m_fingerprint[41];
- /// cached digest length of sha256
- unsigned int m_passphrase_digest_len;
-};
+void gpg_store_init(struct gpg_store *gpg, const char *path);
+int gpg_store_check(struct gpg_store *gpg, const char *passphrase);
+int gpg_store_digest(struct gpg_store *gpg, char *out, const char *in);
+char *gpg_store_get_fingerprint(struct gpg_store *gpg);
+//
+///**
+// *
+// * \brief Interface to the encrypted key storage for both identity public key and the key used for encryption of the identity public key.
+// *
+// */
+//class GpgStore {
+//
+// public:
+// /// Sets correct context values for underlying \c gcrypt operations.
+// GpgStore();
+// /**
+// *
+// * Attempts to decrypt the identity public key with the given passphrase.
+// *
+// * If no public key exists, one will be created and encrypted using the passphrase.
+// *
+// * \param p path to key store
+// * \param passphrase passphrase for public key encryption
+// * \return 0 if successful, any other value indicates an error
+// *
+// */
+// int check(std::string p, std::string passphrase);
+// /**
+// *
+// * Returns the fingerprint of the identity public key.
+// *
+// * \return 160-bit fingerprint value
+// */
+// char *get_fingerprint();
+//
+// private:
+// /// calculates sha256 digest for the given string value, using secure memory
+// int digest(char *out, std::string in);
+// //const char *m_version;
+// //char *m_seckey;
+// /// cached fingerprint value, in string format with zero terminator
+// char m_fingerprint[41];
+// /// cached digest length of sha256
+// unsigned int m_passphrase_digest_len;
+//};
#endif
diff --git a/src/gtk/context.c b/src/gtk/context.c
@@ -0,0 +1,23 @@
+#include <string.h>
+
+#include "context.h"
+#include "settings.h"
+#include "camera.h"
+#include "err.h"
+#include "gpg.h"
+
+
+int kee_context_new(struct kee_context *ctx, struct kee_settings *settings) {
+ memset(ctx, 0, sizeof(struct kee_context));
+ ctx->state = 1;
+ ctx->settings = settings;
+
+ return ERR_OK;
+}
+
+int kee_context_state(struct kee_context *ctx) {
+ return ctx->state;
+}
+
+void kee_context_free(struct kee_context *ctx) {
+}
diff --git a/src/gtk/context.h b/src/gtk/context.h
@@ -0,0 +1,24 @@
+#ifndef _KEE_CONTEXT
+#define _KEE_CONTEXT
+
+#include "settings.h"
+#include "db.h"
+#include "camera.h"
+#include "gpg.h"
+#include "kee-entry-store.h"
+
+
+struct kee_context {
+ void *front;
+ struct kee_settings *settings;
+ struct kee_camera_devices camera_devices;
+ struct db_ctx db;
+ KeeEntryStore *entry_store;
+ int state;
+};
+
+int kee_context_new(struct kee_context *ctx, struct kee_settings *settings);
+int kee_context_state(struct kee_context *ctx);
+void kee_context_free(struct kee_context *ctx);
+
+#endif // _KEE_CONTEXT
diff --git a/src/gtk/kee-key.c b/src/gtk/kee-key.c
@@ -2,6 +2,9 @@
#include <gtk/gtk.h>
#include "kee-key.h"
+#include "gpg.h"
+#include "err.h"
+
typedef struct {
} KeeKeyPrivate;
@@ -12,13 +15,40 @@ struct _KeeKEyClass {
struct _KeeKey {
GtkWidget parent;
+ struct gpg_store gpg;
};
G_DEFINE_TYPE(KeeKey, kee_key, GTK_TYPE_BOX);
-//static GParamSpec *kee_props[KEE_N_IMPORT_PROPS] = {NULL,};
+static GParamSpec *kee_props[KEE_N_KEY_PROPS] = {NULL,};
static guint kee_sigs[KEE_N_KEY_SIGS] = {0,};
+static void kee_key_set_property(GObject *oo, guint property_id, const GValue *value, GParamSpec *pspec) {
+ KeeKey *o = KEE_KEY(oo);
+ gchar *s;
+
+ switch((enum KEE_KEY_PROPS)property_id) {
+ case KEE_P_KEY_STORE_PATH:
+ s = g_value_get_string(value);
+ gpg_store_init(&o->gpg, (char*)s);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(oo, property_id, pspec);
+ }
+}
+
+static void kee_key_get_property(GObject *oo, guint property_id, GValue *value, GParamSpec *pspec) {
+ KeeKey *o = KEE_KEY(oo);
+
+ switch((enum KEE_KEY_PROPS)property_id) {
+ case KEE_P_KEY_STORE:
+ g_value_set_pointer(value, &o->gpg);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(oo, property_id, pspec);
+ }
+}
+
static void kee_key_class_init(KeeKeyClass *kls) {
GObjectClass *o = G_OBJECT_CLASS(kls);
@@ -32,32 +62,61 @@ static void kee_key_class_init(KeeKeyClass *kls) {
G_TYPE_NONE,
0,
NULL);
+
+ o->set_property = kee_key_set_property;
+ o->get_property = kee_key_get_property;
+
+ kee_props[KEE_P_KEY_STORE_PATH] = g_param_spec_string(
+ "keystore_path",
+ "Keystore path",
+ "GPG keystore interface path initializer",
+ ".",
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE);
+
+
+ kee_props[KEE_P_KEY_STORE] = g_param_spec_pointer(
+ "keystore",
+ "Keystore",
+ "GPG keystore interface",
+ G_PARAM_READABLE);
+
+ g_object_class_install_properties(o, KEE_N_KEY_PROPS, kee_props);
}
static void kee_key_init(KeeKey *o) {
}
-static void kee_key_handle_unlock_click(GtkWidget *button, GObject *o) {
+static void kee_key_handle_unlock_click(GtkWidget *button, KeeKey *o) {
+ int r;
GtkEntryBuffer *buf;
- //const char *passphrase;
+ struct gpg_store *gpg;
+ GValue v = G_VALUE_INIT;
+ char passphrase[1024];
- buf = g_object_get_data(o, "passphrase");
- //passphrase = gtk_entry_buffer_get_text(buf);
+ g_value_init(&v, G_TYPE_POINTER);
+ buf = g_object_get_data(G_OBJECT(o), "passphrase");
+ strcpy(passphrase, gtk_entry_buffer_get_text(buf));
g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "click");
- //kee_uicontext_unlock(uctx);
+ g_object_get_property(G_OBJECT(o), "keystore", &v);
+ gpg = g_value_get_pointer(&v);
+ if (r) {
+ g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "wrong passphrase");
+ return;
+ }
+
g_signal_emit(o, kee_sigs[KEE_S_KEY_UNLOCKED], 0);
gtk_entry_buffer_delete_text(buf, 0, gtk_entry_buffer_get_length(buf));
}
-KeeKey* kee_key_new() {
+KeeKey* kee_key_new(const char *key_path) {
KeeKey *o;
GtkWidget *entry;
GtkWidget *button;
GtkEntryBuffer *buf;
- o = g_object_new(KEE_TYPE_KEY, "orientation", GTK_ORIENTATION_VERTICAL, NULL);
+ o = g_object_new(KEE_TYPE_KEY, "keystore_path", key_path, "orientation", GTK_ORIENTATION_VERTICAL, NULL);
entry = gtk_entry_new();
gtk_box_append(GTK_BOX(o), entry);
diff --git a/src/gtk/kee-key.h b/src/gtk/kee-key.h
@@ -9,6 +9,12 @@ G_BEGIN_DECLS
#define KEE_TYPE_KEY kee_key_get_type()
G_DECLARE_FINAL_TYPE(KeeKey, kee_key, KEE, KEY, GtkBox)
+enum KEE_KEY_PROPS {
+ KEE_P_KEY_STORE_PATH = 1,
+ KEE_P_KEY_STORE,
+ KEE_N_KEY_PROPS,
+};
+
enum KEE_KEY_SIGS {
KEE_S_KEY_UNLOCKED,
KEE_N_KEY_SIGS,
diff --git a/src/gtk/main.c b/src/gtk/main.c
@@ -19,9 +19,10 @@ static void startup(GtkApplication *app, struct kee_context *ctx) {
// kee_uicontext_scaninit(uctx);
}
-static void activate(GtkApplication *app, KeeEntryStore *store) { //struct kee_context *ctx) {
- //ui_build(app, ctx);
- ui_build(app, store);
+//static void activate(GtkApplication *app, KeeEntryStore *store) { //struct kee_context *ctx) {
+static void activate(GtkApplication *app, struct kee_context *ctx) {
+ //ui_build(app, store);
+ ui_build(app, ctx);
}
static void deactivate(GtkApplication *app, gpointer user_data) {
@@ -51,9 +52,10 @@ int main(int argc, char **argv) {
db_connect(&ctx.db, "./testdata_mdb");
store = kee_entry_store_new(&ctx.db);
kee_entry_store_set_resolve(store, "./testdata_resource");
+ ctx.entry_store = store;
g_signal_connect (gapp, "startup", G_CALLBACK (startup), &ctx);
- g_signal_connect (gapp, "activate", G_CALLBACK (activate), store);
+ g_signal_connect (gapp, "activate", G_CALLBACK (activate), &ctx);
g_signal_connect (gapp, "shutdown", G_CALLBACK (deactivate), NULL);
//g_signal_connect (uctx, "state", G_CALLBACK(state_log), NULL);
diff --git a/src/gtk/ui.c b/src/gtk/ui.c
@@ -46,19 +46,20 @@ static void ui_handle_unlock(GtkWidget *widget, KeeMenu *menu) {
//}
-//void ui_build(GtkApplication *app, struct kee_context *ctx) {
-void ui_build(GtkApplication *app, KeeEntryStore *store) {
+void ui_build(GtkApplication *app, struct kee_context *ctx) {
GtkWidget *widget;
KeeMenu *win;
KeeImport *import;
+ struct kee_settings *settings;
win = kee_menu_new(app);
- widget = GTK_WIDGET(kee_key_new());
+ settings = ctx->settings;
+ widget = GTK_WIDGET(kee_key_new(settings_get(settings, SETTINGS_KEY)));
kee_menu_add(win, "unlock", widget);
g_signal_connect (widget, "unlock", G_CALLBACK(ui_handle_unlock), win);
- widget = kee_entry_list_new(G_LIST_MODEL(store), win);
+ widget = kee_entry_list_new(G_LIST_MODEL(ctx->entry_store), win);
kee_menu_add(win, "view", widget);
kee_menu_next(win, "view");
diff --git a/src/gtk/ui.h b/src/gtk/ui.h
@@ -2,12 +2,12 @@
#define _UI_H
#include <gtk/gtk.h>
-//#include "context.h"
-#include "kee-entry-store.h"
+#include "context.h"
+//#include "kee-entry-store.h"
//void ui_build(GtkApplication *app, KeeUicontext *uctx);
-//void ui_build(GtkApplication *app, struct kee_context *ctx);
-void ui_build(GtkApplication *app, KeeEntryStore *store);
+void ui_build(GtkApplication *app, struct kee_context *ctx);
+//void ui_build(GtkApplication *app, KeeEntryStore *store);
#endif // _UI_H
diff --git a/src/settings.c b/src/settings.c
@@ -25,6 +25,8 @@ int settings_new_from_xdg(struct kee_settings *z) {
memset(z, 0, sizeof(struct kee_settings));
+ z->key = (unsigned char*)".";
+
z->data = malloc(KEE_SETTINGS_CAP);
p = z->data;
p += KEE_SETTINGS_ITEM_CAP;
@@ -78,6 +80,9 @@ unsigned char *settings_get(struct kee_settings *z, enum SettingsType typ) {
case SETTINGS_RUN:
return z->run;
break;
+ case SETTINGS_KEY:
+ return z->key;
+ break;
case SETTINGS_LOCKTIME:
return z->locktime;
break;
diff --git a/src/settings.h b/src/settings.h
@@ -9,6 +9,7 @@
struct kee_settings {
unsigned char *data;
unsigned char *run;
+ unsigned char *key;
unsigned char *locktime;
unsigned char *video_device;
};
@@ -22,6 +23,8 @@ enum SettingsType {
SETTINGS_DATA = 0x01,
/// Runtime directory
SETTINGS_RUN = 0x02,
+ /// GPG keys directory
+ SETTINGS_KEY = 0x04,
/// Milliseconds a key will stay unlocked since last application use.
SETTINGS_LOCKTIME = 0x10,
/// Default video device to use