[epiphany/wip/ephy-sync: 14/86] Implement key stretch. Obtain authPW and unwrapBKey
- From: Gabriel - Cristian Ivascu <gabrielivascu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [epiphany/wip/ephy-sync: 14/86] Implement key stretch. Obtain authPW and unwrapBKey
- Date: Sat, 30 Jul 2016 17:31:14 +0000 (UTC)
commit cc1cfe44ae5d8e37c0a563275473aa6cdc7ade7c
Author: Gabriel Ivascu <ivascu gabriel59 gmail com>
Date: Thu May 26 18:15:43 2016 +0300
Implement key stretch. Obtain authPW and unwrapBKey
configure.ac | 2 +
src/ephy-sync-service.c | 151 ++++++++++++++++++++++++++++++++++++++++--
src/ephy-sync-service.h | 14 +++-
src/ephy-sync-window.c | 43 +++++++++---
src/resources/sync-dialog.ui | 4 +-
5 files changed, 193 insertions(+), 21 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 1b2c67b..63ab1ff 100644
--- a/configure.ac
+++ b/configure.ac
@@ -82,6 +82,7 @@ LIBNOTIFY_REQUIRED=0.5.1
GCR_REQUIRED=3.5.5
AVAHI_REQUIRED=0.6.22
GVDB_REQUIRED="glib-2.0 >= $GLIB_REQUIRED"
+NETTLE_REQUIRED=3.2
# Tests
@@ -114,6 +115,7 @@ PKG_CHECK_MODULES([DEPENDENCIES], [
gcr-3 >= $GCR_REQUIRED
avahi-gobject >= $AVAHI_REQUIRED
avahi-client >= $AVAHI_REQUIRED
+ nettle >= NETTLE_REQUIRED
])
# Check requirements for gvdb
diff --git a/src/ephy-sync-service.c b/src/ephy-sync-service.c
index 0fda189..54afaea 100644
--- a/src/ephy-sync-service.c
+++ b/src/ephy-sync-service.c
@@ -1,6 +1,9 @@
#include "ephy-sync-service.h"
-#include <stdio.h>
+#include <string.h>
+#include <glib/gstdio.h>
+#include <nettle/hmac.h>
+#include <nettle/pbkdf2.h>
struct _EphySyncService {
GObject parent_instance;
@@ -8,13 +11,99 @@ struct _EphySyncService {
G_DEFINE_TYPE (EphySyncService, ephy_sync_service, G_TYPE_OBJECT);
+static gchar *
+KW (const gchar *name)
+{
+ g_printf ("[%s:%d, %s]\n", __FILE__, __LINE__, __func__);
+ return g_strconcat ("identity.mozilla.com/picl/v1/",
+ name,
+ NULL);
+}
+
+static gchar *
+KWE (const gchar *name, const gchar *emailUTF8)
+{
+ g_printf ("[%s:%d, %s]\n", __FILE__, __LINE__, __func__);
+ return g_strconcat ("identity.mozilla.com/picl/v1/",
+ name,
+ ":",
+ emailUTF8,
+ NULL);
+}
+
+/*
+ * Runs 1000 PBKDF2 iterations using sha256 as hash function.
+ */
+static void pbkdf2_1k (gsize key_length, guint8 *key,
+ gsize salt_length, guint8 *salt,
+ gsize out_length, guint8 *out)
+{
+ g_printf ("[%s:%d, %s]\n", __FILE__, __LINE__, __func__);
+ pbkdf2_hmac_sha256 (key_length, key, 1000, salt_length, salt, out_length, out);
+}
+
+/*
+ * HMAC-based Extract-and-Expand Key Derivation Function.
+ * Uses sha256 as hash function.
+ * https://tools.ietf.org/html/rfc5869
+ */
+static void hkdf (gsize in_length, guint8 *in,
+ gsize salt_length, guint8 *salt,
+ gsize info_length, guint8 *info,
+ gsize out_length, guint8 *out)
+{
+ struct hmac_sha256_ctx ctx;
+ const gsize hash_length = 32;
+ gsize i, offset = 0;
+ guint8 *tmp, *prk;
+ guint8 counter;
+
+ g_printf ("[%s:%d, %s]\n", __FILE__, __LINE__, __func__);
+
+ if (out_length > hash_length * 255)
+ return;
+
+ /* If salt value was not provided, use an array of hash_length zeros */
+ if (salt == NULL) {
+ salt = g_malloc0 (hash_length);
+ salt_length = hash_length;
+ }
+
+ tmp = g_malloc0 (hash_length + info_length + 1);
+ prk = g_malloc0 (hash_length);
+
+ /* Step 1: Extract */
+ hmac_sha256_set_key (&ctx, salt_length, salt);
+ hmac_sha256_update (&ctx, in_length, in);
+ hmac_sha256_digest (&ctx, hash_length, prk);
+
+ /* Step 2: Expand */
+ hmac_sha256_set_key (&ctx, hash_length, prk);
+
+ for (i = 0, counter = 1; i < out_length; i += hash_length, counter++) {
+ memcpy (tmp + offset, info, info_length);
+ tmp[offset + info_length] = counter;
+
+ hmac_sha256_update (&ctx, offset + info_length + 1, tmp);
+ hmac_sha256_digest (&ctx, hash_length, tmp);
+
+ offset = hash_length;
+
+ memcpy (out + i, tmp, hash_length);
+ }
+
+ g_free (salt);
+ g_free (tmp);
+ g_free (prk);
+}
+
static void
ephy_sync_service_class_init (EphySyncServiceClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class = object_class; // suppress warnings
- printf ("[%s:%d, %s]\n", __FILE__, __LINE__, __func__);
+ g_printf ("[%s:%d, %s]\n", __FILE__, __LINE__, __func__);
// TODO: Set finalize, dispose, set/get property methods
}
@@ -22,20 +111,70 @@ ephy_sync_service_class_init (EphySyncServiceClass *klass)
static void
ephy_sync_service_init (EphySyncService *self)
{
- printf ("[%s:%d, %s]\n", __FILE__, __LINE__, __func__);
+ g_printf ("[%s:%d, %s]\n", __FILE__, __LINE__, __func__);
}
EphySyncService *
ephy_sync_service_new (void)
{
- printf ("[%s:%d, %s]\n", __FILE__, __LINE__, __func__);
+ g_printf ("[%s:%d, %s]\n", __FILE__, __LINE__, __func__);
return EPHY_SYNC_SERVICE (g_object_new (EPHY_TYPE_SYNC_SERVICE,
NULL));
}
void
-ephy_sync_service_stretch (void)
+ephy_sync_service_stretch (EphySyncService *self,
+ const gchar *emailUTF8,
+ const gchar *passwordUTF8,
+ guint8 *authPW,
+ guint8 *unwrapBKey)
{
- printf ("[%s:%d, %s]\n", __FILE__, __LINE__, __func__);
+ gchar *salt_stretch;
+ gchar *info_auth;
+ gchar *info_unwrap;
+ guint8 *quickStretchedPW;
+
+ g_return_if_fail (EPHY_IS_SYNC_SERVICE (self));
+
+ g_printf ("[%s:%d, %s]\n", __FILE__, __LINE__, __func__);
+
+ salt_stretch = KWE ("quickStretch", emailUTF8);
+ quickStretchedPW = g_malloc0 (TOKEN_LENGTH);
+ pbkdf2_1k (strlen (passwordUTF8), (guint8 *) passwordUTF8,
+ strlen (salt_stretch), (guint8 *) salt_stretch,
+ TOKEN_LENGTH, quickStretchedPW);
+
+ ephy_sync_service_display_hex ("quickStretchedPW", TOKEN_LENGTH, quickStretchedPW);
+
+ info_auth = KW ("authPW");
+ hkdf (TOKEN_LENGTH, quickStretchedPW,
+ 0, NULL,
+ strlen (info_auth), (guint8 *) info_auth,
+ TOKEN_LENGTH, authPW);
+
+ info_unwrap = KW ("unwrapBkey");
+ hkdf (TOKEN_LENGTH, quickStretchedPW,
+ 0, NULL,
+ strlen (info_unwrap), (guint8 *) info_unwrap,
+ TOKEN_LENGTH, unwrapBKey);
+
+ g_free (salt_stretch);
+ g_free (info_unwrap);
+ g_free (info_auth);
+ g_free (quickStretchedPW);
+}
+
+void
+ephy_sync_service_display_hex (const gchar *name, gsize length, guint8 *data)
+{
+ g_printf ("[%s:%d, %s]\n", __FILE__, __LINE__, __func__);
+
+ g_printf ("%s:\n", name);
+ for (gsize i = 0; i < length; i++) {
+ g_printf ("%02x", data[i]);
+ if ((i + 1) % 8 == 0)
+ g_printf ("\n");
+ }
+ g_printf ("\n");
}
diff --git a/src/ephy-sync-service.h b/src/ephy-sync-service.h
index d685963..5fdb681 100644
--- a/src/ephy-sync-service.h
+++ b/src/ephy-sync-service.h
@@ -5,12 +5,20 @@
G_BEGIN_DECLS
-#define EPHY_TYPE_SYNC_SERVICE (ephy_sync_service_get_type())
+#define EPHY_TYPE_SYNC_SERVICE (ephy_sync_service_get_type ())
+#define TOKEN_LENGTH 32
G_DECLARE_FINAL_TYPE (EphySyncService, ephy_sync_service, EPHY, SYNC_SERVICE, GObject)
-EphySyncService *ephy_sync_service_new (void);
-void ephy_sync_service_stretch (void);
+EphySyncService *ephy_sync_service_new (void);
+void ephy_sync_service_stretch (EphySyncService *self,
+ const gchar *emailUTF8,
+ const gchar *passwordUTF8,
+ guint8 *authPW,
+ guint8 *unwrapBKey);
+void ephy_sync_service_display_hex (const gchar *name,
+ gsize length,
+ guint8 *data);
G_END_DECLS
diff --git a/src/ephy-sync-window.c b/src/ephy-sync-window.c
index 8d23b6e..b47981b 100644
--- a/src/ephy-sync-window.c
+++ b/src/ephy-sync-window.c
@@ -1,6 +1,8 @@
#include "ephy-sync-window.h"
+#include "ephy-sync-service.h"
#include "ephy-gui.h"
+#include <glib/gstdio.h>
#include <gtk/gtk.h>
struct _EphySyncWindow {
@@ -27,15 +29,36 @@ enum {
static GParamSpec *obj_properties[PROP_LAST];
static void
-quickstretch (GSimpleAction *action,
- GVariant *parameter,
- gpointer user_data)
+submit_action (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
{
+ const gchar *emailUTF8;
+ const gchar *passwordUTF8;
+ guint8 *authPW;
+ guint8 *unwrapBKey;
EphySyncWindow *self = EPHY_SYNC_WINDOW (user_data);
- printf ("[%s:%d, %s]\n", __FILE__, __LINE__, __func__);
+ g_printf ("[%s:%d, %s]\n", __FILE__, __LINE__, __func__);
- printf("email:%s\n", gtk_entry_get_text (GTK_ENTRY (self->entry_email)));
- printf("password:%s\n", gtk_entry_get_text (GTK_ENTRY (self->entry_password)));
+ emailUTF8 = gtk_entry_get_text (GTK_ENTRY (self->entry_email));
+ passwordUTF8 = gtk_entry_get_text (GTK_ENTRY (self->entry_password));
+ g_printf ("email: %s\n", emailUTF8);
+ g_printf ("password: %s\n", passwordUTF8);
+
+ authPW = g_malloc0 (TOKEN_LENGTH);
+ unwrapBKey = g_malloc0 (TOKEN_LENGTH);
+
+ ephy_sync_service_stretch (self->sync_service,
+ emailUTF8,
+ passwordUTF8,
+ authPW,
+ unwrapBKey);
+
+ ephy_sync_service_display_hex ("authPW", TOKEN_LENGTH, authPW);
+ ephy_sync_service_display_hex ("unwrapBKey", TOKEN_LENGTH, unwrapBKey);
+
+ g_free (authPW);
+ g_free (unwrapBKey);
}
static void
@@ -98,7 +121,7 @@ create_action_group (EphySyncWindow *self)
GSimpleActionGroup *group;
const GActionEntry entries[] = {
- { "quickstretch", quickstretch }
+ { "submit_action", submit_action }
};
group = g_simple_action_group_new ();
@@ -113,7 +136,7 @@ ephy_sync_window_class_init (EphySyncWindowClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
- printf ("[%s:%d, %s]\n", __FILE__, __LINE__, __func__);
+ g_printf ("[%s:%d, %s]\n", __FILE__, __LINE__, __func__);
object_class->set_property = ephy_sync_window_set_property;
object_class->get_property = ephy_sync_window_get_property;
@@ -139,7 +162,7 @@ ephy_sync_window_class_init (EphySyncWindowClass *klass)
static void
ephy_sync_window_init (EphySyncWindow *self)
{
- printf ("[%s:%d, %s]\n", __FILE__, __LINE__, __func__);
+ g_printf ("[%s:%d, %s]\n", __FILE__, __LINE__, __func__);
gtk_widget_init_template (GTK_WIDGET (self));
@@ -156,7 +179,7 @@ ephy_sync_window_new (EphySyncService *sync_service)
{
EphySyncWindow *self;
- printf ("[%s:%d, %s]\n", __FILE__, __LINE__, __func__);
+ g_printf ("[%s:%d, %s]\n", __FILE__, __LINE__, __func__);
self = g_object_new (EPHY_TYPE_SYNC_WINDOW,
"use-header-bar", TRUE,
diff --git a/src/resources/sync-dialog.ui b/src/resources/sync-dialog.ui
index 2e95416..df88b37 100644
--- a/src/resources/sync-dialog.ui
+++ b/src/resources/sync-dialog.ui
@@ -88,12 +88,12 @@
</child>
<child>
<object class="GtkButton" id="btn_submit">
- <property name="label" translatable="yes">_Stretch</property>
+ <property name="label" translatable="yes">_Submit</property>
<property name="visible">True</property>
<property name="use-underline">True</property>
<property name="sensitive">True</property>
<property name="valign">center</property>
- <property name="action-name">sync.quickstretch</property>
+ <property name="action-name">sync.submit_action</property>
<style>
<class name="suggested-action"/>
<class name="text-button"/>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]