[epiphany/wip/ephy-sync] Move crypto functions to a new module



commit e39aec96c113c36581c05ca7437e7dcbd01e57a2
Author: Gabriel Ivascu <ivascu gabriel59 gmail com>
Date:   Fri Jun 10 00:01:23 2016 +0300

    Move crypto functions to a new module

 src/Makefile.am         |    2 +
 src/ephy-sync-crypto.c  |  144 +++++++++++++++++++++++++++++++++++++++
 src/ephy-sync-crypto.h  |   51 ++++++++++++++
 src/ephy-sync-service.c |  173 ++++++++--------------------------------------
 src/ephy-sync-service.h |    5 +-
 src/ephy-sync-window.c  |   23 +++---
 6 files changed, 240 insertions(+), 158 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 7acc5b1..dbb0f41 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -47,6 +47,8 @@ libephymain_la_SOURCES = \
        ephy-sync-window.h                      \
        ephy-sync-service.c                     \
        ephy-sync-service.h                     \
+       ephy-sync-crypto.c                      \
+       ephy-sync-crypto.h                      \
        ephy-link.c                             \
        ephy-link.h                             \
        ephy-link-action.c                      \
diff --git a/src/ephy-sync-crypto.c b/src/ephy-sync-crypto.c
new file mode 100644
index 0000000..edddf8f
--- /dev/null
+++ b/src/ephy-sync-crypto.c
@@ -0,0 +1,144 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ *  Copyright © 2016 Gabriel Ivascu <ivascu gabriel59 gmail com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ephy-sync-crypto.h"
+
+#include <glib/gstdio.h>
+#include <nettle/hmac.h>
+#include <nettle/pbkdf2.h>
+#include <string.h>
+
+static const gchar hex_digits[] = "0123456789abcdef";
+
+gchar *
+ephy_sync_crypto_kw (const gchar *name)
+{
+  return g_strconcat ("identity.mozilla.com/picl/v1/", name, NULL);
+}
+
+gchar *
+ephy_sync_crypto_kwe (const gchar *name,
+                      const gchar *emailUTF8)
+{
+  return g_strconcat ("identity.mozilla.com/picl/v1/", name, ":", emailUTF8, NULL);
+}
+
+gchar *
+ephy_sync_crypto_encode_hex (guint8 *data,
+                             gsize   data_length)
+{
+  gchar *retval = g_malloc (data_length * 2 + 1);
+
+  for (gsize i = 0; i < data_length; i++) {
+    guint8 byte = data[i];
+
+    retval[2 * i] = hex_digits[byte >> 4];
+    retval[2 * i + 1] = hex_digits[byte & 0xf];
+  }
+
+  retval[data_length * 2] = 0;
+
+  return retval;
+}
+
+/*
+ * Runs 1000 iterations of PBKDF2.
+ * Uses sha256 as hash function.
+ */
+void
+ephy_sync_crypto_pbkdf2_1k (guint8 *key,
+                            gsize   key_length,
+                            guint8 *salt,
+                            gsize   salt_length,
+                            guint8 *out,
+                            gsize   out_length)
+{
+  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
+ */
+void
+ephy_sync_crypto_hkdf (guint8 *in,
+                       gsize   in_length,
+                       guint8 *salt,
+                       gsize   salt_length,
+                       guint8 *info,
+                       gsize   info_length,
+                       guint8 *out,
+                       gsize   out_length)
+{
+  struct hmac_sha256_ctx ctx;
+  const gsize hash_length = 32;
+  gsize i, offset = 0;
+  guint8 *tmp, *prk;
+  guint8 counter;
+
+  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);
+}
+
+void
+ephy_sync_crypto_display_hex (guint8      *data,
+                              gsize        data_length,
+                              const gchar *data_name)
+{
+  g_printf ("%s:\n", data_name);
+  for (gsize i = 0; i < data_length; i++) {
+    g_printf ("%02x", data[i]);
+    if ((i + 1) % 8 == 0)
+      g_printf ("\n");
+  }
+  g_printf ("\n");
+}
diff --git a/src/ephy-sync-crypto.h b/src/ephy-sync-crypto.h
new file mode 100644
index 0000000..7b7d1d0
--- /dev/null
+++ b/src/ephy-sync-crypto.h
@@ -0,0 +1,51 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ *  Copyright © 2016 Gabriel Ivascu <ivascu gabriel59 gmail com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef EPHY_EMBED_UTILS_H
+#define EPHY_EMBED_UTILS_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+gchar *ephy_sync_crypto_kw          (const gchar *name);
+gchar *ephy_sync_crypto_kwe         (const gchar *name,
+                                     const gchar *emailUTF8);
+gchar *ephy_sync_crypto_encode_hex  (guint8 *data,
+                                     gsize   data_length);
+void   ephy_sync_crypto_pbkdf2_1k   (guint8 *key,
+                                     gsize   key_length,
+                                     guint8 *salt,
+                                     gsize   salt_length,
+                                     guint8 *out,
+                                     gsize   out_length);
+void   ephy_sync_crypto_hkdf        (guint8 *in,
+                                     gsize   in_length,
+                                     guint8 *salt,
+                                     gsize   salt_length,
+                                     guint8 *info,
+                                     gsize   info_length,
+                                     guint8 *out,
+                                     gsize   out_length);
+void   ephy_sync_crypto_display_hex (guint8      *data,
+                                     gsize        data_length,
+                                     const gchar *data_name);
+
+G_END_DECLS
+
+#endif
diff --git a/src/ephy-sync-service.c b/src/ephy-sync-service.c
index a1123ab..a2d28af 100644
--- a/src/ephy-sync-service.c
+++ b/src/ephy-sync-service.c
@@ -1,3 +1,4 @@
+#include "ephy-sync-crypto.h"
 #include "ephy-sync-service.h"
 
 #include <string.h>
@@ -13,113 +14,6 @@ struct _EphySyncService {
 
 G_DEFINE_TYPE (EphySyncService, ephy_sync_service, G_TYPE_OBJECT);
 
-static const gchar hex_digits[] = "0123456789abcdef";
-
-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);
-}
-
-static gchar *
-encode_hex (guint8 *data,
-            gsize   data_len)
-{
-  gchar *retval = g_malloc (data_len * 2 + 1);
-
-  for (gsize i = 0; i < data_len; i++) {
-    guint8 byte = data[i];
-
-    retval[2 * i] = hex_digits[byte >> 4];
-    retval[2 * i + 1] = hex_digits[byte & 0xf];
-  }
-
-  retval[data_len * 2] = 0;
-
-  return retval;
-}
-
-/*
- * 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)
 {
@@ -183,7 +77,7 @@ ephy_sync_service_try_login (EphySyncService *self,
   message = soup_message_new (SOUP_METHOD_POST,
                               "https://api.accounts.firefox.com/v1/account/login";);
 
-  authPW_hex = encode_hex (authPW, TOKEN_LENGTH);
+  authPW_hex = ephy_sync_crypto_encode_hex (authPW, EPHY_SYNC_SERVICE_TOKEN_LENGTH);
   request_body = g_strconcat ("{\"authPW\": \"",
                               authPW_hex,
                               "\", \"email\": \"",
@@ -219,44 +113,37 @@ ephy_sync_service_stretch (EphySyncService *self,
 
   g_printf ("[%s:%d, %s]\n", __FILE__, __LINE__, __func__);
 
-  salt_stretch = KWE ("quickStretch", emailUTF8);
-  quickStretchedPW = g_malloc (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);
+  salt_stretch = ephy_sync_crypto_kwe ("quickStretch", emailUTF8);
+  quickStretchedPW = g_malloc (EPHY_SYNC_SERVICE_TOKEN_LENGTH);
+  ephy_sync_crypto_pbkdf2_1k ((guint8 *) passwordUTF8,
+                              strlen (passwordUTF8),
+                              (guint8 *) salt_stretch,
+                              strlen (salt_stretch),
+                              quickStretchedPW,
+                              EPHY_SYNC_SERVICE_TOKEN_LENGTH);
+
+  ephy_sync_crypto_display_hex (quickStretchedPW, EPHY_SYNC_SERVICE_TOKEN_LENGTH, "quickStretchedPW");
+
+  info_auth = ephy_sync_crypto_kw ("authPW");
+  ephy_sync_crypto_hkdf (quickStretchedPW,
+                         EPHY_SYNC_SERVICE_TOKEN_LENGTH,
+                         NULL, 0,
+                         (guint8 *) info_auth,
+                         strlen (info_auth),
+                         authPW,
+                         EPHY_SYNC_SERVICE_TOKEN_LENGTH);
+
+  info_unwrap = ephy_sync_crypto_kw ("unwrapBkey");
+  ephy_sync_crypto_hkdf (quickStretchedPW,
+                         EPHY_SYNC_SERVICE_TOKEN_LENGTH,
+                         NULL, 0,
+                         (guint8 *) info_unwrap,
+                         strlen (info_unwrap),
+                         unwrapBKey,
+                         EPHY_SYNC_SERVICE_TOKEN_LENGTH);
 
   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 3b37926..d77c04b 100644
--- a/src/ephy-sync-service.h
+++ b/src/ephy-sync-service.h
@@ -6,7 +6,7 @@
 G_BEGIN_DECLS
 
 #define EPHY_TYPE_SYNC_SERVICE  (ephy_sync_service_get_type ())
-#define TOKEN_LENGTH            32
+#define EPHY_SYNC_SERVICE_TOKEN_LENGTH  32
 
 G_DECLARE_FINAL_TYPE (EphySyncService, ephy_sync_service, EPHY, SYNC_SERVICE, GObject)
 
@@ -22,9 +22,6 @@ void             ephy_sync_service_try_login    (EphySyncService *self,
                                                  guint8 *authPW,
                                                  guint8 *sessionToken,
                                                  guint8 *keyFetchToken);
-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 db50189..0e9d2d8 100644
--- a/src/ephy-sync-window.c
+++ b/src/ephy-sync-window.c
@@ -1,10 +1,11 @@
-#include "ephy-sync-window.h"
-#include "ephy-sync-service.h"
 #include "ephy-gui.h"
+#include "ephy-sync-crypto.h"
+#include "ephy-sync-service.h"
+#include "ephy-sync-window.h"
 
-#include <string.h>
 #include <glib/gstdio.h>
 #include <gtk/gtk.h>
+#include <string.h>
 
 struct _EphySyncWindow {
   GtkDialog parent_instance;
@@ -54,26 +55,26 @@ submit_action (GSimpleAction *action,
     passwordUTF8 = g_strdup ("pässwörd");
   }
 
-  authPW = g_malloc (TOKEN_LENGTH);
-  unwrapBKey = g_malloc (TOKEN_LENGTH);
+  authPW = g_malloc (EPHY_SYNC_SERVICE_TOKEN_LENGTH);
+  unwrapBKey = g_malloc (EPHY_SYNC_SERVICE_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);
+  ephy_sync_crypto_display_hex (authPW, EPHY_SYNC_SERVICE_TOKEN_LENGTH, "authPW");
+  ephy_sync_crypto_display_hex (unwrapBKey, EPHY_SYNC_SERVICE_TOKEN_LENGTH, "unwrapBKey");
 
-  sessionToken = g_malloc (TOKEN_LENGTH);
-  keyFetchToken = g_malloc0 (TOKEN_LENGTH);
+  sessionToken = g_malloc (EPHY_SYNC_SERVICE_TOKEN_LENGTH);
+  keyFetchToken = g_malloc (EPHY_SYNC_SERVICE_TOKEN_LENGTH);
   ephy_sync_service_try_login (self->sync_service,
                                FALSE,
                                emailUTF8,
                                authPW,
                                sessionToken,
                                keyFetchToken);
-  ephy_sync_service_display_hex ("sessionToken", TOKEN_LENGTH, sessionToken);
-  ephy_sync_service_display_hex ("keyFetchToken", TOKEN_LENGTH, keyFetchToken);
+  ephy_sync_crypto_display_hex (sessionToken, EPHY_SYNC_SERVICE_TOKEN_LENGTH, "sessionToken");
+  ephy_sync_crypto_display_hex (keyFetchToken, EPHY_SYNC_SERVICE_TOKEN_LENGTH, "keyFetchToken");
 
   g_free (authPW);
   g_free (unwrapBKey);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]