[epiphany/wip/sync: 7/19] sync: Discard ephy-sync-utils



commit 19a7ce0cc4d20b41d2c1e5706faeb7ff15aad57b
Author: Gabriel Ivascu <ivascu gabriel59 gmail com>
Date:   Wed Apr 5 18:11:08 2017 +0300

    sync: Discard ephy-sync-utils

 src/Makefile.am               |    2 -
 src/bookmarks/ephy-bookmark.c |   19 +++--
 src/sync/ephy-sync-crypto.c   |  166 +++++++++++++++++++++++++----------------
 src/sync/ephy-sync-crypto.h   |   11 ++-
 src/sync/ephy-sync-secret.c   |   31 +++++---
 src/sync/ephy-sync-service.c  |  137 +++++++++++++++++++++++++---------
 src/sync/ephy-sync-service.h  |    9 ++-
 src/sync/ephy-sync-utils.c    |  160 ---------------------------------------
 src/sync/ephy-sync-utils.h    |   45 -----------
 9 files changed, 249 insertions(+), 331 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index b6357f7..43d7c34 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -79,8 +79,6 @@ libephymain_la_SOURCES = \
        sync/ephy-sync-secret.h                 \
        sync/ephy-sync-service.c                \
        sync/ephy-sync-service.h                \
-       sync/ephy-sync-utils.c                  \
-       sync/ephy-sync-utils.h                  \
        sync/ephy-synchronizable.c              \
        sync/ephy-synchronizable.h              \
        sync/ephy-synchronizable-manager.c      \
diff --git a/src/bookmarks/ephy-bookmark.c b/src/bookmarks/ephy-bookmark.c
index 5774740..262cf8d 100644
--- a/src/bookmarks/ephy-bookmark.c
+++ b/src/bookmarks/ephy-bookmark.c
@@ -24,7 +24,6 @@
 
 #include "ephy-shell.h"
 #include "ephy-sync-crypto.h"
-#include "ephy-sync-utils.h"
 #include "ephy-synchronizable.h"
 
 #include <string.h>
@@ -420,17 +419,23 @@ ephy_bookmark_synchronizable_to_bso (EphySynchronizable  *synchronizable,
                                      SyncCryptoKeyBundle *bundle)
 {
   EphyBookmark *bookmark = EPHY_BOOKMARK (synchronizable);
-  char *bso = NULL;
+  JsonNode *node;
+  JsonObject *object;
+  char *bso;
   char *serialized;
   char *payload;
 
   serialized = json_gobject_to_data (G_OBJECT (bookmark), NULL);
   payload = ephy_sync_crypto_encrypt_record (serialized, bundle);
-  bso = ephy_sync_utils_build_json_string (FALSE,
-                                           "id", bookmark->id,
-                                           "payload", payload,
-                                           NULL);
-
+  node = json_node_new (JSON_NODE_OBJECT);
+  object = json_object_new ();
+  json_object_set_string_member (object, "id", bookmark->id);
+  json_object_set_string_member (object, "payload", payload);
+  json_node_set_object (node, object);
+  bso = json_to_string (node, FALSE);
+
+  json_object_unref (object);
+  json_node_unref (node);
   g_free (payload);
   g_free (serialized);
 
diff --git a/src/sync/ephy-sync-crypto.c b/src/sync/ephy-sync-crypto.c
index 172a607..eb58971 100644
--- a/src/sync/ephy-sync-crypto.c
+++ b/src/sync/ephy-sync-crypto.c
@@ -21,8 +21,6 @@
 #include "config.h"
 #include "ephy-sync-crypto.h"
 
-#include "ephy-sync-utils.h"
-
 #include <glib/gstdio.h>
 #include <inttypes.h>
 #include <libsoup/soup.h>
@@ -206,8 +204,8 @@ ephy_sync_crypto_key_bundle_from_array (JsonArray *array)
 
   aes_key = g_base64_decode (json_array_get_string_element (array, 0), &len);
   hmac_key = g_base64_decode (json_array_get_string_element (array, 1), &len);
-  aes_key_hex = ephy_sync_crypto_encode_hex (aes_key, 0);
-  hmac_key_hex = ephy_sync_crypto_encode_hex (hmac_key, 0);
+  aes_key_hex = ephy_sync_crypto_encode_hex (aes_key, 32);
+  hmac_key_hex = ephy_sync_crypto_encode_hex (hmac_key, 32);
   bundle = ephy_sync_crypto_key_bundle_new (aes_key_hex, hmac_key_hex);
 
   g_free (aes_key);
@@ -273,6 +271,43 @@ ephy_sync_crypto_equals (const guint8 *a,
 }
 
 static char *
+ephy_sync_crypto_find_and_replace (const char *where,
+                                   const char *to_find,
+                                   const char *to_repl)
+{
+  const char *haystack = where;
+  const char *needle = NULL;
+  char *out;
+  gsize haystack_len;
+  gsize to_find_len;
+  gsize to_repl_len;
+  gsize new_len = 0;
+  gsize skip_len = 0;
+
+  g_assert (where);
+  g_assert (to_find);
+  g_assert (to_repl);
+
+  haystack_len = strlen (where);
+  to_find_len = strlen (to_find);
+  to_repl_len = strlen (to_repl);
+  out = g_malloc (haystack_len + 1);
+
+  while ((needle = g_strstr_len (haystack, -1, to_find)) != NULL) {
+    haystack_len += to_find_len - to_repl_len;
+    out = g_realloc (out, haystack_len + 1);
+    skip_len = needle - haystack;
+    memcpy (out + new_len, haystack, skip_len);
+    memcpy (out + new_len + skip_len, to_repl, to_repl_len);
+    new_len += skip_len + to_repl_len;
+    haystack = needle + to_find_len;
+  }
+  strcpy (out + new_len, haystack);
+
+  return out;
+}
+
+static char *
 ephy_sync_crypto_normalize_string (const char              *type,
                                    SyncCryptoHawkArtifacts *artifacts)
 {
@@ -297,8 +332,8 @@ ephy_sync_crypto_normalize_string (const char              *type,
                           NULL);
 
   if (artifacts->ext && strlen (artifacts->ext) > 0) {
-    tmp = ephy_sync_utils_find_and_replace (artifacts->ext, "\\", "\\\\");
-    n_ext = ephy_sync_utils_find_and_replace (tmp, "\n", "\\n");
+    tmp = ephy_sync_crypto_find_and_replace (artifacts->ext, "\\", "\\\\");
+    n_ext = ephy_sync_crypto_find_and_replace (tmp, "\n", "\\n");
     g_free (tmp);
   }
 
@@ -682,7 +717,8 @@ ephy_sync_crypto_process_key_fetch_token (const char  *keyFetchToken,
                                           guint8     **tokenID,
                                           guint8     **reqHMACkey,
                                           guint8     **respHMACkey,
-                                          guint8     **respXORkey)
+                                          guint8     **respXORkey,
+                                          gsize        token_len)
 {
   guint8 *kft;
   guint8 *out1;
@@ -700,32 +736,32 @@ ephy_sync_crypto_process_key_fetch_token (const char  *keyFetchToken,
   kft = ephy_sync_crypto_decode_hex (keyFetchToken);
   info_kft = ephy_sync_crypto_kw ("keyFetchToken");
   info_keys = ephy_sync_crypto_kw ("account/keys");
-  out1 = g_malloc (3 * EPHY_SYNC_TOKEN_LENGTH);
-  out2 = g_malloc (3 * EPHY_SYNC_TOKEN_LENGTH);
+  out1 = g_malloc (3 * token_len);
+  out2 = g_malloc (3 * token_len);
 
   /* Use the keyFetchToken to derive tokenID, reqHMACkey and keyRequestKey. */
-  ephy_sync_crypto_hkdf (kft, EPHY_SYNC_TOKEN_LENGTH,
+  ephy_sync_crypto_hkdf (kft, token_len,
                          NULL, 0,
                          (guint8 *)info_kft, strlen (info_kft),
-                         out1, 3 * EPHY_SYNC_TOKEN_LENGTH);
+                         out1, 3 * token_len);
 
-  *tokenID = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
-  *reqHMACkey = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
-  keyRequestKey = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
-  memcpy (*tokenID, out1, EPHY_SYNC_TOKEN_LENGTH);
-  memcpy (*reqHMACkey, out1 + EPHY_SYNC_TOKEN_LENGTH, EPHY_SYNC_TOKEN_LENGTH);
-  memcpy (keyRequestKey, out1 + 2 * EPHY_SYNC_TOKEN_LENGTH, EPHY_SYNC_TOKEN_LENGTH);
+  *tokenID = g_malloc (token_len);
+  *reqHMACkey = g_malloc (token_len);
+  keyRequestKey = g_malloc (token_len);
+  memcpy (*tokenID, out1, token_len);
+  memcpy (*reqHMACkey, out1 + token_len, token_len);
+  memcpy (keyRequestKey, out1 + 2 * token_len, token_len);
 
   /* Use the keyRequestKey to derive respHMACkey and respXORkey. */
-  ephy_sync_crypto_hkdf (keyRequestKey, EPHY_SYNC_TOKEN_LENGTH,
+  ephy_sync_crypto_hkdf (keyRequestKey, token_len,
                          NULL, 0,
                          (guint8 *)info_keys, strlen (info_keys),
-                         out2, 3 * EPHY_SYNC_TOKEN_LENGTH);
+                         out2, 3 * token_len);
 
-  *respHMACkey = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
-  *respXORkey = g_malloc (2 * EPHY_SYNC_TOKEN_LENGTH);
-  memcpy (*respHMACkey, out2, EPHY_SYNC_TOKEN_LENGTH);
-  memcpy (*respXORkey, out2 + EPHY_SYNC_TOKEN_LENGTH, 2 * EPHY_SYNC_TOKEN_LENGTH);
+  *respHMACkey = g_malloc (token_len);
+  *respXORkey = g_malloc (2 * token_len);
+  memcpy (*respHMACkey, out2, token_len);
+  memcpy (*respXORkey, out2 + token_len, 2 * token_len);
 
   g_free (kft);
   g_free (out1);
@@ -739,7 +775,8 @@ void
 ephy_sync_crypto_process_session_token (const char  *sessionToken,
                                         guint8     **tokenID,
                                         guint8     **reqHMACkey,
-                                        guint8     **requestKey)
+                                        guint8     **requestKey,
+                                        gsize        token_len)
 {
   guint8 *st;
   guint8 *out;
@@ -752,20 +789,20 @@ ephy_sync_crypto_process_session_token (const char  *sessionToken,
 
   st = ephy_sync_crypto_decode_hex (sessionToken);
   info = ephy_sync_crypto_kw ("sessionToken");
-  out = g_malloc (3 * EPHY_SYNC_TOKEN_LENGTH);
+  out = g_malloc (3 * token_len);
 
   /* Use the sessionToken to derive tokenID, reqHMACkey and requestKey. */
-  ephy_sync_crypto_hkdf (st, EPHY_SYNC_TOKEN_LENGTH,
+  ephy_sync_crypto_hkdf (st, token_len,
                          NULL, 0,
                          (guint8 *)info, strlen (info),
-                         out, 3 * EPHY_SYNC_TOKEN_LENGTH);
+                         out, 3 * token_len);
 
-  *tokenID = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
-  *reqHMACkey = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
-  *requestKey = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
-  memcpy (*tokenID, out, EPHY_SYNC_TOKEN_LENGTH);
-  memcpy (*reqHMACkey, out + EPHY_SYNC_TOKEN_LENGTH, EPHY_SYNC_TOKEN_LENGTH);
-  memcpy (*requestKey, out + 2 * EPHY_SYNC_TOKEN_LENGTH, EPHY_SYNC_TOKEN_LENGTH);
+  *tokenID = g_malloc (token_len);
+  *reqHMACkey = g_malloc (token_len);
+  *requestKey = g_malloc (token_len);
+  memcpy (*tokenID, out, token_len);
+  memcpy (*reqHMACkey, out + token_len, token_len);
+  memcpy (*requestKey, out + 2 * token_len, token_len);
 
   g_free (st);
   g_free (out);
@@ -778,7 +815,8 @@ ephy_sync_crypto_compute_sync_keys (const char    *bundle_hex,
                                     const guint8  *respXORkey,
                                     const guint8  *unwrapBKey,
                                     guint8       **kA,
-                                    guint8       **kB)
+                                    guint8       **kB,
+                                    gsize          key_len)
 {
   guint8 *bundle;
   guint8 *ciphertext;
@@ -797,17 +835,17 @@ ephy_sync_crypto_compute_sync_keys (const char    *bundle_hex,
   g_return_val_if_fail (kB, FALSE);
 
   bundle = ephy_sync_crypto_decode_hex (bundle_hex);
-  ciphertext = g_malloc (2 * EPHY_SYNC_TOKEN_LENGTH);
-  respMAC = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
+  ciphertext = g_malloc (2 * key_len);
+  respMAC = g_malloc (key_len);
 
   /* Compute the MAC and compare it to the expected value. */
-  memcpy (ciphertext, bundle, 2 * EPHY_SYNC_TOKEN_LENGTH);
-  memcpy (respMAC, bundle + 2 * EPHY_SYNC_TOKEN_LENGTH, EPHY_SYNC_TOKEN_LENGTH);
+  memcpy (ciphertext, bundle, 2 * key_len);
+  memcpy (respMAC, bundle + 2 * key_len, key_len);
   respMAC2_hex = g_compute_hmac_for_data (G_CHECKSUM_SHA256,
-                                          respHMACkey, EPHY_SYNC_TOKEN_LENGTH,
-                                          ciphertext, 2 * EPHY_SYNC_TOKEN_LENGTH);
+                                          respHMACkey, key_len,
+                                          ciphertext, 2 * key_len);
   respMAC2 = ephy_sync_crypto_decode_hex (respMAC2_hex);
-  if (!ephy_sync_crypto_equals (respMAC, respMAC2, EPHY_SYNC_TOKEN_LENGTH)) {
+  if (!ephy_sync_crypto_equals (respMAC, respMAC2, key_len)) {
     g_warning ("HMAC values differs from the one expected");
     retval = FALSE;
     goto out;
@@ -815,13 +853,13 @@ ephy_sync_crypto_compute_sync_keys (const char    *bundle_hex,
 
   /* XOR the extracted ciphertext with the respXORkey, then split in into the
    * separate kA and wrap(kB) values. */
-  xored = ephy_sync_crypto_xor (ciphertext, respXORkey, 2 * EPHY_SYNC_TOKEN_LENGTH);
-  *kA = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
-  memcpy (*kA, xored, EPHY_SYNC_TOKEN_LENGTH);
-  wrapKB = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
-  memcpy (wrapKB, xored + EPHY_SYNC_TOKEN_LENGTH, EPHY_SYNC_TOKEN_LENGTH);
+  xored = ephy_sync_crypto_xor (ciphertext, respXORkey, 2 * key_len);
+  *kA = g_malloc (key_len);
+  memcpy (*kA, xored, key_len);
+  wrapKB = g_malloc (key_len);
+  memcpy (wrapKB, xored + key_len, key_len);
   /* Finally, XOR wrap(kB) with unwrapBKey to obtain kB. There is no MAC on wrap(kB). */
-  *kB = ephy_sync_crypto_xor (unwrapBKey, wrapKB, EPHY_SYNC_TOKEN_LENGTH);
+  *kB = ephy_sync_crypto_xor (unwrapBKey, wrapKB, key_len);
 
   g_free (wrapKB);
   g_free (xored);
@@ -961,6 +999,8 @@ char *
 ephy_sync_crypto_encrypt_record (const char          *cleartext,
                                  SyncCryptoKeyBundle *bundle)
 {
+  JsonNode *node;
+  JsonObject *object;
   char *payload;
   char *iv_b64;
   char *ciphertext_b64;
@@ -989,14 +1029,16 @@ ephy_sync_crypto_encrypt_record (const char          *cleartext,
   /* SHA256 expects a 32 bytes key. */
   hmac = g_compute_hmac_for_string (G_CHECKSUM_SHA256, hmac_key, 32, ciphertext_b64, -1);
 
-  /* Wrap everything up into a JSON string. Since this is going to be part of
-   * another JSON string, the double quotes need to be escaped. */
-  payload = ephy_sync_utils_build_json_string (TRUE,
-                                               "ciphertext", ciphertext_b64,
-                                               "IV", iv_b64,
-                                               "hmac", hmac,
-                                               NULL);
+  node = json_node_new (JSON_NODE_OBJECT);
+  object = json_object_new ();
+  json_object_set_string_member (object, "ciphertext", ciphertext_b64);
+  json_object_set_string_member (object, "IV", iv_b64);
+  json_object_set_string_member (object, "hmac", hmac);
+  json_node_set_object (node, object);
+  payload = json_to_string (node, FALSE);
 
+  json_object_unref (object);
+  json_node_unref (node);
   g_free (hmac);
   g_free (iv_b64);
   g_free (ciphertext_b64);
@@ -1034,7 +1076,7 @@ ephy_sync_crypto_compute_hawk_header (const char            *url,
   g_return_val_if_fail (id, NULL);
   g_return_val_if_fail (key, NULL);
 
-  ts = ephy_sync_utils_current_time_seconds ();
+  ts = g_get_real_time () / 1000000;
   hash = options ? g_strdup (options->hash) : NULL;
   payload = options ? options->payload : NULL;
   timestamp = options ? options->timestamp : NULL;
@@ -1096,8 +1138,8 @@ ephy_sync_crypto_compute_hawk_header (const char            *url,
     char *h_ext;
     char *tmp_ext;
 
-    tmp_ext = ephy_sync_utils_find_and_replace (artifacts->ext, "\\", "\\\\");
-    h_ext = ephy_sync_utils_find_and_replace (tmp_ext, "\n", "\\n");
+    tmp_ext = ephy_sync_crypto_find_and_replace (artifacts->ext, "\\", "\\\\");
+    h_ext = ephy_sync_crypto_find_and_replace (tmp_ext, "\n", "\\n");
     header = ephy_sync_crypto_append_to_header (header, "ext", h_ext);
 
     g_free (h_ext);
@@ -1283,21 +1325,17 @@ ephy_sync_crypto_encode_hex (const guint8 *data,
                              gsize         data_len)
 {
   char *retval;
-  gsize length;
 
   g_return_val_if_fail (data, NULL);
 
-  length = data_len == 0 ? EPHY_SYNC_TOKEN_LENGTH : data_len;
-  retval = g_malloc (length * 2 + 1);
-
-  for (gsize i = 0; i < length; i++) {
+  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[length * 2] = 0;
+  retval[data_len * 2] = 0;
 
   return retval;
 }
diff --git a/src/sync/ephy-sync-crypto.h b/src/sync/ephy-sync-crypto.h
index 420aebf..ce2b33c 100644
--- a/src/sync/ephy-sync-crypto.h
+++ b/src/sync/ephy-sync-crypto.h
@@ -26,8 +26,6 @@
 
 G_BEGIN_DECLS
 
-#define EPHY_SYNC_TOKEN_LENGTH 32
-
 typedef struct {
   char *app;
   char *dlg;
@@ -86,17 +84,20 @@ void                    ephy_sync_crypto_process_key_fetch_token  (const char
                                                                    guint8                **tokenID,
                                                                    guint8                **reqHMACkey,
                                                                    guint8                **respHMACkey,
-                                                                   guint8                **respXORkey);
+                                                                   guint8                **respXORkey,
+                                                                   gsize                   token_len);
 void                    ephy_sync_crypto_process_session_token    (const char             *sessionToken,
                                                                    guint8                **tokenID,
                                                                    guint8                **reqHMACkey,
-                                                                   guint8                **requestKey);
+                                                                   guint8                **requestKey,
+                                                                   gsize                   token_len);
 gboolean                ephy_sync_crypto_compute_sync_keys        (const char             *bundle_hex,
                                                                    const guint8           *respHMACkey,
                                                                    const guint8           *respXORkey,
                                                                    const guint8           *unwrapBKey,
                                                                    guint8                **kA,
-                                                                   guint8                **kB);
+                                                                   guint8                **kB,
+                                                                   gsize                   key_len);
 SyncCryptoKeyBundle    *ephy_sync_crypto_derive_key_bundle        (const guint8           *key,
                                                                    gsize                   key_len);
 char                   *ephy_sync_crypto_decrypt_record           (const char             *payload,
diff --git a/src/sync/ephy-sync-secret.c b/src/sync/ephy-sync-secret.c
index 975baf2..9d3b6dc 100644
--- a/src/sync/ephy-sync-secret.c
+++ b/src/sync/ephy-sync-secret.c
@@ -153,7 +153,7 @@ load_tokens_cb (SecretService *service,
   for (GList *m = members; m != NULL; m = m->next) {
     ephy_sync_service_set_token (sync_service,
                                  json_object_get_string_member (json, m->data),
-                                 ephy_sync_utils_token_type_from_name (m->data));
+                                 ephy_sync_service_token_type_from_name (m->data));
   }
 
 out:
@@ -205,19 +205,26 @@ store_tokens_cb (SecretService *service,
 void
 ephy_sync_secret_store_tokens (EphySyncService *service)
 {
+  JsonNode *node;
+  JsonObject *object;
   SecretValue *value;
   GHashTable *attributes;
   char *tokens;
   char *label;
 
-  tokens = ephy_sync_utils_build_json_string (FALSE,
-                                              ephy_sync_utils_token_name_from_type (TOKEN_UID),
-                                              ephy_sync_service_get_token (service, TOKEN_UID),
-                                              ephy_sync_utils_token_name_from_type (TOKEN_SESSIONTOKEN),
-                                              ephy_sync_service_get_token (service, TOKEN_SESSIONTOKEN),
-                                              ephy_sync_utils_token_name_from_type (TOKEN_KB),
-                                              ephy_sync_service_get_token (service, TOKEN_KB),
-                                              NULL);
+  node = json_node_new (JSON_NODE_OBJECT);
+  object = json_object_new ();
+  json_object_set_string_member (object,
+                                 ephy_sync_service_token_name_from_type (TOKEN_UID),
+                                 ephy_sync_service_get_token (service, TOKEN_UID));
+  json_object_set_string_member (object,
+                                 ephy_sync_service_token_name_from_type (TOKEN_SESSIONTOKEN),
+                                 ephy_sync_service_get_token (service, TOKEN_SESSIONTOKEN));
+  json_object_set_string_member (object,
+                                 ephy_sync_service_token_name_from_type (TOKEN_KB),
+                                 ephy_sync_service_get_token (service, TOKEN_KB));
+  json_node_set_object (node, object);
+  tokens = json_to_string (node, FALSE);
   value = secret_value_new (tokens, -1, "text/plain");
   attributes = secret_attributes_build (EPHY_SYNC_TOKEN_SCHEMA, EMAIL_KEY,
                                         ephy_sync_service_get_user_email (service),
@@ -230,8 +237,10 @@ ephy_sync_secret_store_tokens (EphySyncService *service)
                         NULL, label, value, NULL,
                         (GAsyncReadyCallback)store_tokens_cb, service);
 
-  g_free (tokens);
   g_free (label);
-  secret_value_unref (value);
   g_hash_table_unref (attributes);
+  secret_value_unref (value);
+  g_free (tokens);
+  json_object_unref (object);
+  json_node_unref (node);
 }
diff --git a/src/sync/ephy-sync-service.c b/src/sync/ephy-sync-service.c
index 2bd0da1..067d9ae 100644
--- a/src/sync/ephy-sync-service.c
+++ b/src/sync/ephy-sync-service.c
@@ -38,6 +38,7 @@
 #define CERTIFICATE_DURATION      (60 * 60 * 1000) /* milliseconds, limited to 24 hours */
 #define ASSERTION_DURATION        (5 * 60)         /* seconds */
 #define STORAGE_VERSION           5
+#define TOKEN_LENGTH              32
 
 struct _EphySyncService {
   GObject      parent_instance;
@@ -165,12 +166,12 @@ sign_in_async_data_new (const char   *email,
   data->sessionToken = g_strdup (sessionToken);
   data->unwrapBKey = g_strdup (unwrapBKey);
   data->tokenID_hex = g_strdup (tokenID_hex);
-  data->reqHMACkey = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
-  memcpy (data->reqHMACkey, reqHMACkey, EPHY_SYNC_TOKEN_LENGTH);
-  data->respHMACkey = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
-  memcpy (data->respHMACkey, respHMACkey, EPHY_SYNC_TOKEN_LENGTH);
-  data->respXORkey = g_malloc (2 * EPHY_SYNC_TOKEN_LENGTH);
-  memcpy (data->respXORkey, respXORkey, 2 * EPHY_SYNC_TOKEN_LENGTH);
+  data->reqHMACkey = g_malloc (TOKEN_LENGTH);
+  memcpy (data->reqHMACkey, reqHMACkey, TOKEN_LENGTH);
+  data->respHMACkey = g_malloc (TOKEN_LENGTH);
+  memcpy (data->respHMACkey, respHMACkey, TOKEN_LENGTH);
+  data->respXORkey = g_malloc (2 * TOKEN_LENGTH);
+  memcpy (data->respXORkey, respXORkey, 2 * TOKEN_LENGTH);
 
   return data;
 }
@@ -253,7 +254,7 @@ ephy_sync_service_storage_credentials_is_expired (EphySyncService *self)
     return TRUE;
 
   /* Consider a 60 seconds safety interval. */
-  return self->storage_credentials_expiry_time < ephy_sync_utils_current_time_seconds () - 60;
+  return self->storage_credentials_expiry_time < g_get_real_time () / 1000000 - 60;
 }
 
 static void
@@ -510,7 +511,7 @@ obtain_storage_credentials_cb (SoupSession *session,
   self->storage_endpoint = g_strdup (json_object_get_string_member (json, "api_endpoint"));
   self->storage_credentials_id = g_strdup (json_object_get_string_member (json, "id"));
   self->storage_credentials_key = g_strdup (json_object_get_string_member (json, "key"));
-  self->storage_credentials_expiry_time = json_object_get_int_member (json, "duration") + 
ephy_sync_utils_current_time_seconds ();
+  self->storage_credentials_expiry_time = json_object_get_int_member (json, "duration") + g_get_real_time () 
/ 1000000;
   is_internal_error = FALSE;
 
 free_node:
@@ -521,6 +522,34 @@ out:
     ephy_sync_service_send_next_storage_request (self);
 }
 
+static char *
+get_audience (const char *url)
+{
+  SoupURI *uri;
+  const char *scheme;
+  const char *host;
+  char *audience;
+  char *port;
+
+  g_return_val_if_fail (url, NULL);
+
+  uri = soup_uri_new (url);
+  scheme = soup_uri_get_scheme (uri);
+  host = soup_uri_get_host (uri);
+  /* soup_uri_get_port returns the default port if URI does not have any port. */
+  port = g_strdup_printf (":%u", soup_uri_get_port (uri));
+
+  if (g_strstr_len (url, -1, port))
+    audience = g_strdup_printf ("%s://%s%s", scheme, host, port);
+  else
+    audience = g_strdup_printf ("%s://%s", scheme, host);
+
+  g_free (port);
+  soup_uri_free (uri);
+
+  return audience;
+}
+
 static void
 ephy_sync_service_obtain_storage_credentials (EphySyncService *self)
 {
@@ -536,12 +565,12 @@ ephy_sync_service_obtain_storage_credentials (EphySyncService *self)
   g_assert (self->certificate);
   g_assert (self->keypair);
 
-  audience = ephy_sync_utils_make_audience (MOZILLA_TOKEN_SERVER_URL);
+  audience = get_audience (MOZILLA_TOKEN_SERVER_URL);
   assertion = ephy_sync_crypto_create_assertion (self->certificate, audience,
                                                  ASSERTION_DURATION, self->keypair);
   kB = ephy_sync_crypto_decode_hex (ephy_sync_service_get_token (self, TOKEN_KB));
-  hashed_kB = g_compute_checksum_for_data (G_CHECKSUM_SHA256, kB, EPHY_SYNC_TOKEN_LENGTH);
-  client_state = g_strndup (hashed_kB, EPHY_SYNC_TOKEN_LENGTH);
+  hashed_kB = g_compute_checksum_for_data (G_CHECKSUM_SHA256, kB, TOKEN_LENGTH);
+  client_state = g_strndup (hashed_kB, TOKEN_LENGTH);
   authorization = g_strdup_printf ("BrowserID %s", assertion);
 
   msg = soup_message_new (SOUP_METHOD_GET, MOZILLA_TOKEN_SERVER_URL);
@@ -644,11 +673,13 @@ out:
 static void
 ephy_sync_service_obtain_signed_certificate (EphySyncService *self)
 {
+  JsonNode *node;
+  JsonObject *object_key;
+  JsonObject *object_body;
   guint8 *tokenID;
   guint8 *reqHMACkey;
   guint8 *requestKey;
   char *tokenID_hex;
-  char *public_key_json;
   char *request_body;
   char *n;
   char *e;
@@ -662,26 +693,34 @@ ephy_sync_service_obtain_signed_certificate (EphySyncService *self)
 
   /* Derive tokenID, reqHMACkey and requestKey from the sessionToken. */
   ephy_sync_crypto_process_session_token (ephy_sync_service_get_token (self, TOKEN_SESSIONTOKEN),
-                                          &tokenID, &reqHMACkey, &requestKey);
-  tokenID_hex = ephy_sync_crypto_encode_hex (tokenID, 0);
+                                          &tokenID, &reqHMACkey, &requestKey, TOKEN_LENGTH);
+  tokenID_hex = ephy_sync_crypto_encode_hex (tokenID, TOKEN_LENGTH);
 
   n = mpz_get_str (NULL, 10, self->keypair->public.n);
   e = mpz_get_str (NULL, 10, self->keypair->public.e);
-  public_key_json = ephy_sync_utils_build_json_string (FALSE, "algorithm", "RS", "n", n, "e", e, NULL);
-  request_body = g_strdup_printf ("{\"publicKey\": %s, \"duration\": %d}",
-                                  public_key_json, CERTIFICATE_DURATION);
+  node = json_node_new (JSON_NODE_OBJECT);
+  object_body = json_object_new ();
+  json_object_set_int_member (object_body, "duration", CERTIFICATE_DURATION);
+  object_key = json_object_new ();
+  json_object_set_string_member (object_key, "algorithm", "RS");
+  json_object_set_string_member (object_key, "n", n);
+  json_object_set_string_member (object_key, "e", e);
+  json_object_set_object_member (object_body, "publicKey", object_key);
+  json_node_set_object (node, object_body);
+  request_body = json_to_string (node, FALSE);
   ephy_sync_service_fxa_hawk_post_async (self, "certificate/sign", tokenID_hex,
-                                         reqHMACkey, EPHY_SYNC_TOKEN_LENGTH, request_body,
+                                         reqHMACkey, TOKEN_LENGTH, request_body,
                                          obtain_signed_certificate_cb, NULL);
 
-  g_free (tokenID);
-  g_free (reqHMACkey);
-  g_free (requestKey);
-  g_free (tokenID_hex);
-  g_free (public_key_json);
   g_free (request_body);
-  g_free (n);
+  json_object_unref (object_body);
+  json_node_unref (node);
   g_free (e);
+  g_free (n);
+  g_free (tokenID_hex);
+  g_free (requestKey);
+  g_free (reqHMACkey);
+  g_free (tokenID);
 }
 
 static void
@@ -966,6 +1005,33 @@ ephy_sync_service_set_token (EphySyncService   *self,
   }
 }
 
+const char *
+ephy_sync_service_token_name_from_type (EphySyncTokenType type)
+{
+  switch (type) {
+    case TOKEN_UID:
+      return "uid";
+    case TOKEN_SESSIONTOKEN:
+      return "sessionToken";
+    case TOKEN_KB:
+      return "kB";
+    default:
+      g_assert_not_reached ();
+  }
+}
+
+EphySyncTokenType
+ephy_sync_service_token_type_from_name (const char *name)
+{
+  if (!g_strcmp0 (name, "uid"))
+    return TOKEN_UID;
+  if (!g_strcmp0 (name, "sessionToken"))
+    return TOKEN_SESSIONTOKEN;
+  if (!g_strcmp0 (name, "kB"))
+    return TOKEN_KB;
+  g_assert_not_reached ();
+}
+
 SyncCryptoKeyBundle *
 ephy_sync_service_get_key_bundle (EphySyncService *self,
                                   const char      *collection)
@@ -1035,8 +1101,8 @@ ephy_sync_service_destroy_session (EphySyncService *self)
 
   url = g_strdup_printf ("%ssession/destroy", MOZILLA_FXA_SERVER_URL);
   ephy_sync_crypto_process_session_token (ephy_sync_service_get_token (self, TOKEN_SESSIONTOKEN),
-                                          &tokenID, &reqHMACkey, &requestKey);
-  tokenID_hex = ephy_sync_crypto_encode_hex (tokenID, 0);
+                                          &tokenID, &reqHMACkey, &requestKey, TOKEN_LENGTH);
+  tokenID_hex = ephy_sync_crypto_encode_hex (tokenID, TOKEN_LENGTH);
 
   msg = soup_message_new (SOUP_METHOD_POST, url);
   soup_message_set_request (msg, content_type, SOUP_MEMORY_STATIC,
@@ -1044,7 +1110,7 @@ ephy_sync_service_destroy_session (EphySyncService *self)
   hoptions = ephy_sync_crypto_hawk_options_new (NULL, NULL, NULL, content_type,
                                                 NULL, NULL, NULL, request_body, NULL);
   hheader = ephy_sync_crypto_compute_hawk_header (url, "POST", tokenID_hex,
-                                                  reqHMACkey, EPHY_SYNC_TOKEN_LENGTH,
+                                                  reqHMACkey, TOKEN_LENGTH,
                                                   hoptions);
   soup_message_headers_append (msg->request_headers, "authorization", hheader->header);
   soup_message_headers_append (msg->request_headers, "content-type", content_type);
@@ -1191,14 +1257,14 @@ ephy_sync_service_conclude_sign_in (EphySyncService *self,
   unwrapKB = ephy_sync_crypto_decode_hex (data->unwrapBKey);
   if (!ephy_sync_crypto_compute_sync_keys (bundle, data->respHMACkey,
                                            data->respXORkey, unwrapKB,
-                                           &kA, &kB)) {
+                                           &kA, &kB, TOKEN_LENGTH)) {
     ephy_sync_service_report_sign_in_error (self,
                                             _("Failed to retrieve the Sync Key"),
                                             FALSE);
     goto out;
   }
 
-  kB_hex = ephy_sync_crypto_encode_hex (kB, 0);
+  kB_hex = ephy_sync_crypto_encode_hex (kB, TOKEN_LENGTH);
 
   /* Save the email and the tokens. */
   ephy_sync_service_set_user_email (self, data->email);
@@ -1254,7 +1320,7 @@ get_account_keys_cb (SoupSession *session,
     if (json_object_get_int_member (json, "errno") == 104) {
       LOG ("Account not verified, retrying...");
       ephy_sync_service_fxa_hawk_get_async (self, "account/keys", data->tokenID_hex,
-                                            data->reqHMACkey, EPHY_SYNC_TOKEN_LENGTH,
+                                            data->reqHMACkey, TOKEN_LENGTH,
                                             get_account_keys_cb, data);
       is_internal_error = FALSE;
       goto free_node;
@@ -1313,17 +1379,16 @@ ephy_sync_service_do_sign_in (EphySyncService *self,
    * endpoint. The server looks up the stored table entry with tokenID, checks
    * the request HMAC for validity, then returns the pre-encrypted response.
    * See https://github.com/mozilla/fxa-auth-server/wiki/onepw-protocol#fetching-sync-keys */
-  ephy_sync_crypto_process_key_fetch_token (keyFetchToken,
-                                            &tokenID, &reqHMACkey,
-                                            &respHMACkey, &respXORkey);
-  tokenID_hex = ephy_sync_crypto_encode_hex (tokenID, 0);
+  ephy_sync_crypto_process_key_fetch_token (keyFetchToken, &tokenID, &reqHMACkey,
+                                            &respHMACkey, &respXORkey, TOKEN_LENGTH);
+  tokenID_hex = ephy_sync_crypto_encode_hex (tokenID, TOKEN_LENGTH);
 
   /* Get the master sync key bundle from the /account/keys endpoint. */
   data = sign_in_async_data_new (email, uid, sessionToken,
                                  unwrapBKey, tokenID_hex,
                                  reqHMACkey, respHMACkey, respXORkey);
   ephy_sync_service_fxa_hawk_get_async (self, "account/keys", tokenID_hex,
-                                        reqHMACkey, EPHY_SYNC_TOKEN_LENGTH,
+                                        reqHMACkey, TOKEN_LENGTH,
                                         get_account_keys_cb, data);
 
   g_free (tokenID_hex);
@@ -1724,7 +1789,7 @@ obtain_sync_key_bundles_cb (SoupSession *session,
    * the first one used as a symmetric encryption key (AES) and the second one
    * used as a HMAC key. */
   kB = ephy_sync_crypto_decode_hex (ephy_sync_service_get_token (self, TOKEN_KB));
-  bundle = ephy_sync_crypto_derive_key_bundle (kB, EPHY_SYNC_TOKEN_LENGTH);
+  bundle = ephy_sync_crypto_derive_key_bundle (kB, TOKEN_LENGTH);
 
   record = ephy_sync_crypto_decrypt_record (payload, bundle);
   if (!record) {
diff --git a/src/sync/ephy-sync-service.h b/src/sync/ephy-sync-service.h
index ce3522e..4687242 100644
--- a/src/sync/ephy-sync-service.h
+++ b/src/sync/ephy-sync-service.h
@@ -21,7 +21,6 @@
 #pragma once
 
 #include "ephy-sync-crypto.h"
-#include "ephy-sync-utils.h"
 #include "ephy-synchronizable-manager.h"
 
 #include <glib-object.h>
@@ -29,6 +28,12 @@
 
 G_BEGIN_DECLS
 
+typedef enum {
+  TOKEN_UID,
+  TOKEN_SESSIONTOKEN,
+  TOKEN_KB
+} EphySyncTokenType;
+
 #define EPHY_TYPE_SYNC_SERVICE (ephy_sync_service_get_type ())
 
 G_DECLARE_FINAL_TYPE (EphySyncService, ephy_sync_service, EPHY, SYNC_SERVICE, GObject)
@@ -43,6 +48,8 @@ const char          *ephy_sync_service_get_token                  (EphySyncServi
 void                 ephy_sync_service_set_token                  (EphySyncService           *self,
                                                                    const char                *value,
                                                                    EphySyncTokenType          type);
+const char          *ephy_sync_service_token_name_from_type       (EphySyncTokenType          type);
+EphySyncTokenType    ephy_sync_service_token_type_from_name       (const char                *name);
 SyncCryptoKeyBundle *ephy_sync_service_get_key_bundle             (EphySyncService           *self,
                                                                    const char                *collection);
 void                 ephy_sync_service_clear_storage_credentials  (EphySyncService           *self);


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