From 5bef3aecedf1f062cc9ddf9a3b819841a5d989f8 Mon Sep 17 00:00:00 2001 From: Andrej Kacian Date: Sat, 20 Feb 2016 00:27:47 +0100 Subject: [PATCH 1/1] Made the gnutls password encryption work on Win32. --- src/mh.c | 2 +- src/password.c | 67 +++++++++++++++++++++++++++++++++++----------- src/password_gtk.c | 2 -- 3 files changed, 53 insertions(+), 18 deletions(-) diff --git a/src/mh.c b/src/mh.c index 0736e58e0..913a41c9a 100644 --- a/src/mh.c +++ b/src/mh.c @@ -791,7 +791,7 @@ static gint mh_create_tree(Folder *folder) rootpath = LOCAL_FOLDER(folder)->rootpath; #ifdef G_OS_UNIX if (*rootpath == '/') { -#elif G_OS_WIN32 +#elif defined G_OS_WIN32 if (g_ascii_isalpha(*rootpath) && !strncmp(rootpath + 1, "\:", 2)) { #endif /* Folder path is absolute. */ diff --git a/src/password.c b/src/password.c index 4f9ee16e3..7e37e2875 100644 --- a/src/password.c +++ b/src/password.c @@ -30,9 +30,12 @@ #include #include -#ifdef G_OS_UNIX +#if defined G_OS_UNIX #include #include +#elif defined G_OS_WIN32 +#include +#include #endif #include "common/passcrypt.h" @@ -271,8 +274,10 @@ gchar *password_encrypt_gnutls(const gchar *password, gnutls_datum_t key, iv; int ivlen, keylen, digestlen, blocklen, ret, i; unsigned char hashbuf[BUFSIZE], *buf, *encbuf, *base, *output; -#ifdef G_OS_UNIX +#if defined G_OS_UNIX int rnd; +#elif defined G_OS_WIN32 + HCRYPTPROV rnd; #endif g_return_val_if_fail(password != NULL, NULL); @@ -299,38 +304,48 @@ gchar *password_encrypt_gnutls(const gchar *password, memcpy(key.data, &hashbuf, keylen); key.size = keylen; -#ifdef G_OS_UNIX /* Prepare our source of random data. */ +#if defined G_OS_UNIX rnd = open("/dev/urandom", O_RDONLY); if (rnd == -1) { perror("fopen on /dev/urandom"); +#elif defined G_OS_WIN32 + if (!CryptAcquireContext(&rnd, NULL, NULL, PROV_RSA_FULL, 0) && + !CryptAcquireContext(&rnd, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) { + debug_print("Could not acquire a CSP handle.\n"); +#endif g_free(key.data); g_free(iv.data); return NULL; } -#endif /* Prepare random IV for cipher */ iv.data = malloc(ivlen); iv.size = ivlen; -#ifdef G_OS_UNIX +#if defined G_OS_UNIX ret = read(rnd, iv.data, ivlen); if (ret != ivlen) { perror("read into iv"); + close(rnd); +#elif defined G_OS_WIN32 + if (!CryptGenRandom(rnd, ivlen, iv.data)) { + debug_print("Could not read random data for IV\n"); + CryptReleaseContext(rnd, 0); +#endif g_free(key.data); g_free(iv.data); - close(rnd); return NULL; } -#endif /* Initialize the encryption */ ret = gnutls_cipher_init(&handle, algo, &key, &iv); if (ret < 0) { g_free(key.data); g_free(iv.data); -#ifdef G_OS_UNIX +#if defined G_OS_UNIX close(rnd); +#elif defined G_OS_WIN32 + CryptReleaseContext(rnd, 0); #endif return NULL; } @@ -339,20 +354,28 @@ gchar *password_encrypt_gnutls(const gchar *password, * rest with zero bytes. */ buf = malloc(BUFSIZE + blocklen); memset(buf, 0, BUFSIZE); -#ifdef G_OS_UNIX +#if defined G_OS_UNIX ret = read(rnd, buf, blocklen); if (ret != blocklen) { perror("read into buffer"); + close(rnd); +#elif defined G_OS_WIN32 + if (!CryptGenRandom(rnd, blocklen, buf)) { + debug_print("Could not read random data for IV\n"); + CryptReleaseContext(rnd, 0); +#endif g_free(buf); g_free(key.data); g_free(iv.data); - close(rnd); gnutls_cipher_deinit(handle); return NULL; } /* We don't need any more random data. */ +#if defined G_OS_UNIX close(rnd); +#elif defined G_OS_WIN32 + CryptReleaseContext(rnd, 0); #endif memcpy(buf + blocklen, password, strlen(password)); @@ -398,8 +421,10 @@ gchar *password_decrypt_gnutls(const gchar *password, int ivlen, keylen, digestlen, blocklen, ret, i; gsize len; unsigned char hashbuf[BUFSIZE], *buf; -#ifdef G_OS_UNIX +#if defined G_OS_UNIX int rnd; +#elif defined G_OS_WIN32 + HCRYPTPROV rnd; #endif g_return_val_if_fail(password != NULL, NULL); @@ -452,34 +477,46 @@ gchar *password_decrypt_gnutls(const gchar *password, memcpy(key.data, &hashbuf, keylen); key.size = keylen; -#ifdef G_OS_UNIX /* Prepare our source of random data. */ +#if defined G_OS_UNIX rnd = open("/dev/urandom", O_RDONLY); if (rnd == -1) { perror("fopen on /dev/urandom"); +#elif defined G_OS_WIN32 + if (!CryptAcquireContext(&rnd, NULL, NULL, PROV_RSA_FULL, 0) && + !CryptAcquireContext(&rnd, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) { + debug_print("Could not acquire a CSP handle.\n"); +#endif g_free(key.data); g_free(iv.data); g_strfreev(tokens); return NULL; } -#endif /* Prepare random IV for cipher */ iv.data = malloc(ivlen); iv.size = ivlen; -#ifdef G_OS_UNIX +#if defined G_OS_UNIX ret = read(rnd, iv.data, ivlen); if (ret != ivlen) { perror("read into iv"); + close(rnd); +#elif defined G_OS_WIN32 + if (!CryptGenRandom(rnd, ivlen, iv.data)) { + debug_print("Could not read random data for IV\n"); + CryptReleaseContext(rnd, 0); +#endif g_free(key.data); g_free(iv.data); g_strfreev(tokens); - close(rnd); return NULL; } /* We don't need any more random data. */ +#if defined G_OS_UNIX close(rnd); +#elif defined G_OS_WIN32 + CryptReleaseContext(rnd, 0); #endif /* Prepare encrypted password string for decryption. */ diff --git a/src/password_gtk.c b/src/password_gtk.c index 683acbe21..41bb7f566 100644 --- a/src/password_gtk.c +++ b/src/password_gtk.c @@ -218,8 +218,6 @@ void master_password_change_dialog() while (!ctx->done) gtk_main_iteration(); - manage_window_focus_out(dialog, NULL, NULL); - if (ctx->dialog != NULL) gtk_widget_destroy(ctx->dialog); -- 2.25.1