[epiphany/wip/ephy-sync: 120/126] sync: More consistent code
- From: Gabriel - Cristian Ivascu <gabrielivascu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [epiphany/wip/ephy-sync: 120/126] sync: More consistent code
- Date: Fri, 19 Aug 2016 17:41:39 +0000 (UTC)
commit def2b2234ff70b39e2d7c812f1f09330da3e68d2
Author: Gabriel Ivascu <ivascu gabriel59 gmail com>
Date: Sun Aug 14 03:12:11 2016 +0300
sync: More consistent code
src/ephy-bookmark.c | 4 +-
src/ephy-sync-bookmarks.c | 6 +-
src/ephy-sync-bookmarks.h | 6 +-
src/ephy-sync-crypto.c | 707 +++++++++++++++++++++------------------------
src/ephy-sync-crypto.h | 120 ++++-----
src/ephy-sync-secret.c | 65 ++---
src/ephy-sync-secret.h | 18 +-
src/ephy-sync-service.c | 536 ++++++++++++++--------------------
src/ephy-sync-service.h | 45 +--
src/ephy-sync-utils.c | 135 ++++++++-
src/ephy-sync-utils.h | 29 ++-
src/prefs-dialog.c | 4 +-
12 files changed, 805 insertions(+), 870 deletions(-)
---
diff --git a/src/ephy-bookmark.c b/src/ephy-bookmark.c
index d9fde77..51f1a41 100644
--- a/src/ephy-bookmark.c
+++ b/src/ephy-bookmark.c
@@ -188,7 +188,7 @@ ephy_bookmark_class_init (EphyBookmarkClass *klass)
static void
ephy_bookmark_init (EphyBookmark *self)
{
- self->id = ephy_sync_crypto_generate_random_string (32);
+ self->id = ephy_sync_crypto_generate_random_hex (32);
}
static JsonNode *
@@ -514,7 +514,7 @@ ephy_bookmark_from_bso (JsonObject *bso)
service = ephy_shell_get_global_sync_service (ephy_shell_get_default ());
sync_key = ephy_sync_crypto_decode_hex (ephy_sync_service_get_token (service, TOKEN_KB));
decoded = ephy_sync_crypto_base64_urlsafe_decode (json_object_get_string_member (bso, "payload"),
- &decoded_len);
+ &decoded_len, FALSE);
decrypted = (char *) ephy_sync_crypto_aes_256 (AES_256_MODE_DECRYPT, sync_key,
decoded, decoded_len, NULL);
object = json_gobject_from_data (EPHY_TYPE_BOOKMARK, decrypted, -1, &error);
diff --git a/src/ephy-sync-bookmarks.c b/src/ephy-sync-bookmarks.c
index 1ec0b94..0730a56 100644
--- a/src/ephy-sync-bookmarks.c
+++ b/src/ephy-sync-bookmarks.c
@@ -21,7 +21,6 @@
#include "ephy-debug.h"
#include "ephy-shell.h"
-#include "ephy-sync-utils.h"
#define EPHY_BOOKMARKS_DUMMY_BSO "000000000000"
#define EPHY_BOOKMARKS_COLLECTION "ephy-bookmarks"
@@ -158,7 +157,7 @@ upload_bookmark_to_server_response_cb (SoupSession *session,
void
ephy_sync_bookmarks_upload_bookmark_to_server (EphyBookmark *bookmark,
- gboolean force_upload)
+ gboolean force)
{
EphySyncService *service;
gchar *endpoint;
@@ -171,10 +170,9 @@ ephy_sync_bookmarks_upload_bookmark_to_server (EphyBookmark *bookmark,
endpoint = get_storage_endpoint_for_bookmark (bookmark);
bso = ephy_bookmark_to_bso (bookmark);
modified = ephy_bookmark_get_modified (bookmark);
-
ephy_sync_service_send_storage_message (service, endpoint,
SOUP_METHOD_PUT, bso, -1,
- force_upload ? -1 : modified,
+ force ? -1 : modified,
upload_bookmark_to_server_response_cb,
bookmark);
diff --git a/src/ephy-sync-bookmarks.h b/src/ephy-sync-bookmarks.h
index 4fce698..a161d1e 100644
--- a/src/ephy-sync-bookmarks.h
+++ b/src/ephy-sync-bookmarks.h
@@ -27,14 +27,10 @@
G_BEGIN_DECLS
void ephy_sync_bookmarks_create_storage_collection (void);
-
void ephy_sync_bookmarks_upload_bookmark_to_server (EphyBookmark *bookmark,
- gboolean force_upload);
-
+ gboolean force);
void ephy_sync_bookmarks_merge_locals_with_remotes (void);
-
void ephy_sync_bookmarks_check_storage_collection (void);
-
void ephy_sync_bookmarks_delete_storage_collection (void);
G_END_DECLS
diff --git a/src/ephy-sync-crypto.c b/src/ephy-sync-crypto.c
index d928880..3e4a0fb 100644
--- a/src/ephy-sync-crypto.c
+++ b/src/ephy-sync-crypto.c
@@ -19,6 +19,8 @@
#include "config.h"
#include "ephy-sync-crypto.h"
+#include "ephy-sync-utils.h"
+
#include <glib/gstdio.h>
#include <libsoup/soup.h>
#include <nettle/aes.h>
@@ -28,78 +30,74 @@
static const gchar hex_digits[] = "0123456789abcdef";
-static guint8 *
-concatenate_bytes (guint8 *first_data,
- gsize first_length,
- ...) G_GNUC_NULL_TERMINATED;
-
EphySyncCryptoHawkOptions *
-ephy_sync_crypto_hawk_options_new (gchar *app,
- gchar *dlg,
- gchar *ext,
- gchar *content_type,
- gchar *hash,
- gchar *local_time_offset,
- gchar *nonce,
- gchar *payload,
- gchar *timestamp)
-{
- EphySyncCryptoHawkOptions *hawk_options;
-
- hawk_options = g_slice_new (EphySyncCryptoHawkOptions);
- hawk_options->app = app;
- hawk_options->dlg = dlg;
- hawk_options->ext = ext;
- hawk_options->content_type = content_type;
- hawk_options->hash = hash;
- hawk_options->local_time_offset = local_time_offset;
- hawk_options->nonce = nonce;
- hawk_options->payload = payload;
- hawk_options->timestamp = timestamp;
-
- return hawk_options;
+ephy_sync_crypto_hawk_options_new (const gchar *app,
+ const gchar *dlg,
+ const gchar *ext,
+ const gchar *content_type,
+ const gchar *hash,
+ const gchar *local_time_offset,
+ const gchar *nonce,
+ const gchar *payload,
+ const gchar *timestamp)
+{
+ EphySyncCryptoHawkOptions *options;
+
+ options = g_slice_new (EphySyncCryptoHawkOptions);
+ options->app = g_strdup (app);
+ options->dlg = g_strdup (dlg);
+ options->ext = g_strdup (ext);
+ options->content_type = g_strdup (content_type);
+ options->hash = g_strdup (hash);
+ options->local_time_offset = g_strdup (local_time_offset);
+ options->nonce = g_strdup (nonce);
+ options->payload = g_strdup (payload);
+ options->timestamp = g_strdup (timestamp);
+
+ return options;
}
static EphySyncCryptoHawkArtifacts *
-ephy_sync_crypto_hawk_artifacts_new (gchar *app,
- gchar *dlg,
- gchar *ext,
- gchar *hash,
- gchar *host,
- gchar *method,
- gchar *nonce,
- gchar *port,
- gchar *resource,
- gchar *ts)
-{
- EphySyncCryptoHawkArtifacts *hawk_artifacts;
-
- hawk_artifacts = g_slice_new (EphySyncCryptoHawkArtifacts);
- hawk_artifacts->app = app;
- hawk_artifacts->dlg = dlg;
- hawk_artifacts->ext = ext;
- hawk_artifacts->hash = hash;
- hawk_artifacts->host = host;
- hawk_artifacts->method = method;
- hawk_artifacts->nonce = nonce;
- hawk_artifacts->port = port;
- hawk_artifacts->resource = resource;
- hawk_artifacts->ts = ts;
-
- return hawk_artifacts;
+
+ephy_sync_crypto_hawk_artifacts_new (const gchar *app,
+ const gchar *dlg,
+ const gchar *ext,
+ const gchar *hash,
+ const gchar *host,
+ const gchar *method,
+ const gchar *nonce,
+ guint port,
+ const gchar *resource,
+ gint64 ts)
+{
+ EphySyncCryptoHawkArtifacts *artifacts;
+
+ artifacts = g_slice_new (EphySyncCryptoHawkArtifacts);
+ artifacts->app = g_strdup (app);
+ artifacts->dlg = g_strdup (dlg);
+ artifacts->ext = g_strdup (ext);
+ artifacts->hash = g_strdup (hash);
+ artifacts->host = g_strdup (host);
+ artifacts->method = g_strdup (method);
+ artifacts->nonce = g_strdup (nonce);
+ artifacts->port = g_strdup_printf ("%u", port);
+ artifacts->resource = g_strdup (resource);
+ artifacts->ts = g_strdup_printf ("%ld", ts);
+
+ return artifacts;
}
static EphySyncCryptoHawkHeader *
ephy_sync_crypto_hawk_header_new (gchar *header,
EphySyncCryptoHawkArtifacts *artifacts)
{
- EphySyncCryptoHawkHeader *hawk_header;
+ EphySyncCryptoHawkHeader *hheader;
- hawk_header = g_slice_new (EphySyncCryptoHawkHeader);
- hawk_header->header = header;
- hawk_header->artifacts = artifacts;
+ hheader = g_slice_new (EphySyncCryptoHawkHeader);
+ hheader->header = header;
+ hheader->artifacts = artifacts;
- return hawk_header;
+ return hheader;
}
static EphySyncCryptoRSAKeyPair *
@@ -116,51 +114,51 @@ ephy_sync_crypto_rsa_key_pair_new (struct rsa_public_key public,
}
void
-ephy_sync_crypto_hawk_options_free (EphySyncCryptoHawkOptions *hawk_options)
+ephy_sync_crypto_hawk_options_free (EphySyncCryptoHawkOptions *options)
{
- g_return_if_fail (hawk_options != NULL);
+ g_return_if_fail (options != NULL);
- g_free (hawk_options->app);
- g_free (hawk_options->dlg);
- g_free (hawk_options->ext);
- g_free (hawk_options->content_type);
- g_free (hawk_options->hash);
- g_free (hawk_options->local_time_offset);
- g_free (hawk_options->nonce);
- g_free (hawk_options->payload);
- g_free (hawk_options->timestamp);
+ g_free (options->app);
+ g_free (options->dlg);
+ g_free (options->ext);
+ g_free (options->content_type);
+ g_free (options->hash);
+ g_free (options->local_time_offset);
+ g_free (options->nonce);
+ g_free (options->payload);
+ g_free (options->timestamp);
- g_slice_free (EphySyncCryptoHawkOptions, hawk_options);
+ g_slice_free (EphySyncCryptoHawkOptions, options);
}
static void
-ephy_sync_crypto_hawk_artifacts_free (EphySyncCryptoHawkArtifacts *hawk_artifacts)
+ephy_sync_crypto_hawk_artifacts_free (EphySyncCryptoHawkArtifacts *artifacts)
{
- g_return_if_fail (hawk_artifacts != NULL);
+ g_return_if_fail (artifacts != NULL);
- g_free (hawk_artifacts->app);
- g_free (hawk_artifacts->dlg);
- g_free (hawk_artifacts->ext);
- g_free (hawk_artifacts->hash);
- g_free (hawk_artifacts->host);
- g_free (hawk_artifacts->method);
- g_free (hawk_artifacts->nonce);
- g_free (hawk_artifacts->port);
- g_free (hawk_artifacts->resource);
- g_free (hawk_artifacts->ts);
+ g_free (artifacts->app);
+ g_free (artifacts->dlg);
+ g_free (artifacts->ext);
+ g_free (artifacts->hash);
+ g_free (artifacts->host);
+ g_free (artifacts->method);
+ g_free (artifacts->nonce);
+ g_free (artifacts->port);
+ g_free (artifacts->resource);
+ g_free (artifacts->ts);
- g_slice_free (EphySyncCryptoHawkArtifacts, hawk_artifacts);
+ g_slice_free (EphySyncCryptoHawkArtifacts, artifacts);
}
void
-ephy_sync_crypto_hawk_header_free (EphySyncCryptoHawkHeader *hawk_header)
+ephy_sync_crypto_hawk_header_free (EphySyncCryptoHawkHeader *hheader)
{
- g_return_if_fail (hawk_header != NULL);
+ g_return_if_fail (hheader != NULL);
- g_free (hawk_header->header);
- ephy_sync_crypto_hawk_artifacts_free (hawk_header->artifacts);
+ g_free (hheader->header);
+ ephy_sync_crypto_hawk_artifacts_free (hheader->artifacts);
- g_slice_free (EphySyncCryptoHawkHeader, hawk_header);
+ g_slice_free (EphySyncCryptoHawkHeader, hheader);
}
void
@@ -175,18 +173,23 @@ ephy_sync_crypto_rsa_key_pair_free (EphySyncCryptoRSAKeyPair *keypair)
}
static gchar *
-kw (const gchar *name)
+ephy_sync_crypto_kw (const gchar *name)
{
+ g_return_val_if_fail (name != NULL, NULL);
+
return g_strconcat ("identity.mozilla.com/picl/v1/", name, NULL);
}
static guint8 *
-xor (guint8 *a,
- guint8 *b,
- gsize length)
+ephy_sync_crypto_xor (guint8 *a,
+ guint8 *b,
+ gsize length)
{
guint8 *xored;
+ g_return_val_if_fail (a != NULL, NULL);
+ g_return_val_if_fail (b != NULL, NULL);
+
xored = g_malloc (length);
for (gsize i = 0; i < length; i++)
xored[i] = a[i] ^ b[i];
@@ -195,10 +198,13 @@ xor (guint8 *a,
}
static gboolean
-are_equal (guint8 *a,
- guint8 *b,
- gsize length)
+ephy_sync_crypto_equals (guint8 *a,
+ guint8 *b,
+ gsize length)
{
+ g_return_val_if_fail (a != NULL, FALSE);
+ g_return_val_if_fail (b != NULL, FALSE);
+
for (gsize i = 0; i < length; i++)
if (a[i] != b[i])
return FALSE;
@@ -207,36 +213,8 @@ are_equal (guint8 *a,
}
static gchar *
-find_and_replace_string (const gchar *src,
- const gchar *find,
- const gchar *repl)
-{
- const gchar *haystack = src;
- const gchar *needle = NULL;
- gsize haystack_length = strlen (src);
- gsize find_length = strlen (find);
- gsize repl_length = strlen (repl);
- gsize new_length = 0;
- gsize skip_length = 0;
- gchar *new = g_malloc (haystack_length + 1);
-
- while ((needle = g_strstr_len (haystack, -1, find)) != NULL) {
- haystack_length += find_length - repl_length;
- new = g_realloc (new, haystack_length + 1);
- skip_length = needle - haystack;
- memcpy (new + new_length, haystack, skip_length);
- memcpy (new + new_length + skip_length, repl, repl_length);
- new_length += skip_length + repl_length;
- haystack = needle + find_length;
- }
- strcpy (new + new_length, haystack);
-
- return new;
-}
-
-static gchar *
-normalize_string (const gchar *mac_type,
- EphySyncCryptoHawkArtifacts *artifacts)
+ephy_sync_crypto_normalize_string (const gchar *type,
+ EphySyncCryptoHawkArtifacts *artifacts)
{
gchar *host;
gchar *info;
@@ -245,27 +223,22 @@ normalize_string (const gchar *mac_type,
gchar *normalized;
gchar *tmp;
- g_return_val_if_fail (mac_type, NULL);
- g_return_val_if_fail (artifacts, NULL);
+ g_return_val_if_fail (type != NULL, NULL);
+ g_return_val_if_fail (artifacts != NULL, NULL);
- info = g_strdup_printf ("hawk.%d.%s", HAWK_VERSION, mac_type);
+ info = g_strdup_printf ("hawk.%d.%s", HAWK_VERSION, type);
method = g_ascii_strup (artifacts->method, -1);
host = g_ascii_strdown (artifacts->host, -1);
normalized = g_strjoin ("\n",
- info,
- artifacts->ts,
- artifacts->nonce,
- method,
- artifacts->resource,
- host,
- artifacts->port,
- artifacts->hash ? artifacts->hash : "",
+ info, artifacts->ts, artifacts->nonce,
+ method, artifacts->resource, host,
+ artifacts->port, artifacts->hash ? artifacts->hash : "",
NULL);
if (artifacts->ext && strlen (artifacts->ext) > 0) {
- tmp = find_and_replace_string (artifacts->ext, "\\", "\\\\");
- n_ext = find_and_replace_string (tmp, "\n", "\\n");
+ tmp = ephy_sync_utils_find_and_replace (artifacts->ext, "\\", "\\\\");
+ n_ext = ephy_sync_utils_find_and_replace (tmp, "\n", "\\n");
g_free (tmp);
}
@@ -288,11 +261,13 @@ normalize_string (const gchar *mac_type,
}
static gchar *
-parse_content_type (const gchar *content_type)
+ephy_sync_crypto_parse_content_type (const gchar *content_type)
{
gchar **tokens;
gchar *retval;
+ g_return_val_if_fail (content_type != NULL, NULL);
+
tokens = g_strsplit (content_type, ";", -1);
retval = g_ascii_strdown (g_strstrip (tokens[0]), -1);
g_strfreev (tokens);
@@ -301,8 +276,8 @@ parse_content_type (const gchar *content_type)
}
static gchar *
-calculate_payload_hash (const gchar *payload,
- const gchar *content_type)
+ephy_sync_crypto_calculate_payload_hash (const gchar *payload,
+ const gchar *content_type)
{
guint8 *digest;
gchar *digest_hex;
@@ -310,14 +285,12 @@ calculate_payload_hash (const gchar *payload,
gchar *update;
gchar *hash;
- g_return_val_if_fail (payload, NULL);
- g_return_val_if_fail (content_type, NULL);
+ g_return_val_if_fail (payload != NULL, NULL);
+ g_return_val_if_fail (content_type != NULL, NULL);
- content = parse_content_type (content_type);
+ content = ephy_sync_crypto_parse_content_type (content_type);
update = g_strdup_printf ("hawk.%d.payload\n%s\n%s\n",
- HAWK_VERSION,
- content,
- payload);
+ HAWK_VERSION, content, payload);
digest_hex = g_compute_checksum_for_string (G_CHECKSUM_SHA256, update, -1);
digest = ephy_sync_crypto_decode_hex (digest_hex);
@@ -332,24 +305,22 @@ calculate_payload_hash (const gchar *payload,
}
static gchar *
-calculate_mac (const gchar *mac_type,
- guint8 *key,
- gsize key_length,
- EphySyncCryptoHawkArtifacts *artifacts)
+ephy_sync_crypto_calculate_mac (const gchar *type,
+ guint8 *key,
+ gsize key_len,
+ EphySyncCryptoHawkArtifacts *artifacts)
{
guint8 *digest;
gchar *digest_hex;
gchar *normalized;
gchar *mac;
- g_return_val_if_fail (mac_type, NULL);
- g_return_val_if_fail (key, NULL);
- g_return_val_if_fail (artifacts, NULL);
+ g_return_val_if_fail (type != NULL, NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+ g_return_val_if_fail (artifacts != NULL, NULL);
- normalized = normalize_string (mac_type, artifacts);
- digest_hex = g_compute_hmac_for_string (G_CHECKSUM_SHA256,
- key, key_length,
- normalized, -1);
+ normalized = ephy_sync_crypto_normalize_string (type, artifacts);
+ digest_hex = g_compute_hmac_for_string (G_CHECKSUM_SHA256, key, key_len, normalized, -1);
digest = ephy_sync_crypto_decode_hex (digest_hex);
mac = g_base64_encode (digest, g_checksum_type_get_length (G_CHECKSUM_SHA256));
@@ -361,66 +332,33 @@ calculate_mac (const gchar *mac_type,
}
static gchar *
-append_token_to_header (gchar *header,
- const gchar *token_name,
- gchar *token_value)
+ephy_sync_crypto_append_to_header (gchar *header,
+ const gchar *name,
+ gchar *value)
{
gchar *new_header;
gchar *tmp;
+ g_return_val_if_fail (header != NULL, NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+ g_return_val_if_fail (value != NULL, NULL);
+
tmp = header;
- new_header = g_strconcat (header, ", ",
- token_name, "=\"",
- token_value, "\"",
- NULL);
+ new_header = g_strconcat (header, ", ", name, "=\"", value, "\"", NULL);
g_free (tmp);
return new_header;
}
-static guint8 *
-concatenate_bytes (guint8 *first_data,
- gsize first_length,
- ...)
-{
- va_list args;
- guint8 *data;
- guint8 *out;
- gsize length;
- gsize out_length;
-
- out_length = first_length;
- out = g_malloc (out_length);
- memcpy (out, first_data, out_length);
-
- va_start (args, first_length);
-
- while ((data = va_arg (args, guint8 *)) != NULL) {
- length = va_arg (args, gsize);
- out = g_realloc (out, out_length + length);
- memcpy (out + out_length, data, length);
- out_length += length;
- }
-
- va_end (args);
-
- return out;
-}
-
-/*
- * HMAC-based Extract-and-Expand Key Derivation Function.
- * Uses sha256 as hash function.
- * https://tools.ietf.org/html/rfc5869
- */
static void
-hkdf (guint8 *in,
- gsize in_length,
- guint8 *salt,
- gsize salt_length,
- guint8 *info,
- gsize info_length,
- guint8 *out,
- gsize out_length)
+ephy_sync_crypto_hkdf (guint8 *in,
+ gsize in_len,
+ guint8 *salt,
+ gsize salt_len,
+ guint8 *info,
+ gsize info_len,
+ guint8 *out,
+ gsize out_len)
{
gchar *prk_hex;
gchar *tmp_hex;
@@ -429,56 +367,53 @@ hkdf (guint8 *in,
guint8 *out_full;
guint8 *data;
guint8 counter;
- gsize hash_length;
- gsize data_length;
+ gsize hash_len;
+ gsize data_len;
gsize n;
- hash_length = g_checksum_type_get_length (G_CHECKSUM_SHA256);
- g_assert (out_length <= hash_length * 255);
+ g_return_if_fail (in != NULL);
+ g_return_if_fail (info != NULL);
+ g_return_if_fail (out != NULL);
- /* If salt value was not provided, use an array of hash_length zeros */
+ hash_len = g_checksum_type_get_length (G_CHECKSUM_SHA256);
+ g_assert (out_len <= hash_len * 255);
+
+ /* If salt value was not provided, use an array of hash_len zeros */
if (salt == NULL) {
- salt = g_malloc0 (hash_length);
- salt_length = hash_length;
+ salt = g_malloc0 (hash_len);
+ salt_len = hash_len;
}
/* Step 1: Extract */
- prk_hex = g_compute_hmac_for_data (G_CHECKSUM_SHA256,
- salt, salt_length,
- in, in_length);
+ prk_hex = g_compute_hmac_for_data (G_CHECKSUM_SHA256, salt, salt_len, in, in_len);
prk = ephy_sync_crypto_decode_hex (prk_hex);
/* Step 2: Expand */
counter = 1;
- n = (out_length + hash_length - 1) / hash_length;
- out_full = g_malloc (n * hash_length);
+ n = (out_len + hash_len - 1) / hash_len;
+ out_full = g_malloc (n * hash_len);
for (gsize i = 0; i < n; i++, counter++) {
if (i == 0) {
- data = concatenate_bytes (info, info_length,
- &counter, 1,
- NULL);
- data_length = info_length + 1;
+ data = ephy_sync_utils_concatenate_bytes (info, info_len, &counter, 1, NULL);
+ data_len = info_len + 1;
} else {
- data = concatenate_bytes (out_full + (i - 1) * hash_length, hash_length,
- info, info_length,
- &counter, 1,
- NULL);
- data_length = hash_length + info_length + 1;
+ data = ephy_sync_utils_concatenate_bytes (out_full + (i - 1) * hash_len, hash_len,
+ info, info_len, &counter, 1,
+ NULL);
+ data_len = hash_len + info_len + 1;
}
- tmp_hex = g_compute_hmac_for_data (G_CHECKSUM_SHA256,
- prk, hash_length,
- data, data_length);
+ tmp_hex = g_compute_hmac_for_data (G_CHECKSUM_SHA256, prk, hash_len, data, data_len);
tmp = ephy_sync_crypto_decode_hex (tmp_hex);
- memcpy (out_full + i * hash_length, tmp, hash_length);
+ memcpy (out_full + i * hash_len, tmp, hash_len);
g_free (data);
g_free (tmp);
g_free (tmp_hex);
}
- memcpy (out, out_full, out_length);
+ memcpy (out, out_full, out_len);
g_free (prk_hex);
g_free (salt);
@@ -487,25 +422,29 @@ hkdf (guint8 *in,
}
static void
-random_func (void *ctx,
- gsize length,
- guint8 *dst)
+ephy_sync_crypto_random_gen (void *ctx,
+ gsize length,
+ guint8 *dst)
{
for (gsize i = 0; i < length; i++)
dst[i] = g_random_int ();
}
static void
-base64_to_base64_urlsafe (gchar *text)
+ephy_sync_crypto_b64_to_b64_urlsafe (gchar *text)
{
+ g_return_if_fail (text != NULL);
+
/* Replace '+' with '-' and '/' with '_' */
g_strcanon (text, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789=/", '-');
g_strcanon (text, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789=-", '_');
}
static void
-base64_urlsafe_to_base64 (gchar *text)
+ephy_sync_crypto_b64_urlsafe_to_b64 (gchar *text)
{
+ g_return_if_fail (text != NULL);
+
/* Replace '-' with '+' and '_' with '/' */
g_strcanon (text, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789=_", '+');
g_strcanon (text, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789=+", '/');
@@ -525,16 +464,22 @@ ephy_sync_crypto_process_key_fetch_token (const gchar *keyFetchToken,
gchar *info_kft;
gchar *info_keys;
+ g_return_if_fail (keyFetchToken != NULL);
+ g_return_if_fail (tokenID != NULL);
+ g_return_if_fail (reqHMACkey != NULL);
+ g_return_if_fail (respHMACkey != NULL);
+ g_return_if_fail (respXORkey != NULL);
+
kft = ephy_sync_crypto_decode_hex (keyFetchToken);
- info_kft = kw ("keyFetchToken");
- info_keys = kw ("account/keys");
+ 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);
- hkdf (kft, EPHY_SYNC_TOKEN_LENGTH,
- NULL, 0,
- (guint8 *) info_kft, strlen (info_kft),
- out1, 3 * EPHY_SYNC_TOKEN_LENGTH);
+ ephy_sync_crypto_hkdf (kft, EPHY_SYNC_TOKEN_LENGTH,
+ NULL, 0,
+ (guint8 *) info_kft, strlen (info_kft),
+ out1, 3 * EPHY_SYNC_TOKEN_LENGTH);
*tokenID = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
*reqHMACkey = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
@@ -543,10 +488,10 @@ ephy_sync_crypto_process_key_fetch_token (const gchar *keyFetchToken,
memcpy (*reqHMACkey, out1 + EPHY_SYNC_TOKEN_LENGTH, EPHY_SYNC_TOKEN_LENGTH);
memcpy (keyRequestKey, out1 + 2 * EPHY_SYNC_TOKEN_LENGTH, EPHY_SYNC_TOKEN_LENGTH);
- hkdf (keyRequestKey, EPHY_SYNC_TOKEN_LENGTH,
- NULL, 0,
- (guint8 *) info_keys, strlen (info_keys),
- out2, 3 * EPHY_SYNC_TOKEN_LENGTH);
+ ephy_sync_crypto_hkdf (keyRequestKey, EPHY_SYNC_TOKEN_LENGTH,
+ NULL, 0,
+ (guint8 *) info_keys, strlen (info_keys),
+ out2, 3 * EPHY_SYNC_TOKEN_LENGTH);
*respHMACkey = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
*respXORkey = g_malloc (2 * EPHY_SYNC_TOKEN_LENGTH);
@@ -571,14 +516,19 @@ ephy_sync_crypto_process_session_token (const gchar *sessionToken,
guint8 *out;
gchar *info;
+ g_return_if_fail (sessionToken != NULL);
+ g_return_if_fail (tokenID != NULL);
+ g_return_if_fail (reqHMACkey != NULL);
+ g_return_if_fail (requestKey != NULL);
+
st = ephy_sync_crypto_decode_hex (sessionToken);
- info = kw ("sessionToken");
+ info = ephy_sync_crypto_kw ("sessionToken");
out = g_malloc (3 * EPHY_SYNC_TOKEN_LENGTH);
- hkdf (st, EPHY_SYNC_TOKEN_LENGTH,
- NULL, 0,
- (guint8 *) info, strlen (info),
- out, 3 * EPHY_SYNC_TOKEN_LENGTH);
+ ephy_sync_crypto_hkdf (st, EPHY_SYNC_TOKEN_LENGTH,
+ NULL, 0,
+ (guint8 *) info, strlen (info),
+ out, 3 * EPHY_SYNC_TOKEN_LENGTH);
*tokenID = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
*reqHMACkey = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
@@ -593,12 +543,12 @@ ephy_sync_crypto_process_session_token (const gchar *sessionToken,
}
void
-ephy_sync_crypto_retrieve_sync_keys (const gchar *bundle,
- guint8 *respHMACkey,
- guint8 *respXORkey,
- guint8 *unwrapBKey,
- guint8 **kA,
- guint8 **kB)
+ephy_sync_crypto_compute_sync_keys (const gchar *bundle,
+ guint8 *respHMACkey,
+ guint8 *respXORkey,
+ guint8 *unwrapBKey,
+ guint8 **kA,
+ guint8 **kB)
{
guint8 *bdl;
guint8 *ciphertext;
@@ -608,6 +558,13 @@ ephy_sync_crypto_retrieve_sync_keys (const gchar *bundle,
guint8 *wrapKB;
gchar *respMAC2_hex;
+ g_return_if_fail (bundle != NULL);
+ g_return_if_fail (respHMACkey != NULL);
+ g_return_if_fail (respXORkey != NULL);
+ g_return_if_fail (unwrapBKey != NULL);
+ g_return_if_fail (kA != NULL);
+ g_return_if_fail (kB != NULL);
+
bdl = ephy_sync_crypto_decode_hex (bundle);
ciphertext = g_malloc (2 * EPHY_SYNC_TOKEN_LENGTH);
respMAC = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
@@ -620,12 +577,12 @@ ephy_sync_crypto_retrieve_sync_keys (const gchar *bundle,
respHMACkey, EPHY_SYNC_TOKEN_LENGTH,
ciphertext, 2 * EPHY_SYNC_TOKEN_LENGTH);
respMAC2 = ephy_sync_crypto_decode_hex (respMAC2_hex);
- g_assert (are_equal (respMAC, respMAC2, EPHY_SYNC_TOKEN_LENGTH) == TRUE);
+ g_assert (ephy_sync_crypto_equals (respMAC, respMAC2, EPHY_SYNC_TOKEN_LENGTH) == TRUE);
- xored = xor (ciphertext, respXORkey, 2 * EPHY_SYNC_TOKEN_LENGTH);
+ xored = ephy_sync_crypto_xor (ciphertext, respXORkey, 2 * EPHY_SYNC_TOKEN_LENGTH);
memcpy (*kA, xored, EPHY_SYNC_TOKEN_LENGTH);
memcpy (wrapKB, xored + EPHY_SYNC_TOKEN_LENGTH, EPHY_SYNC_TOKEN_LENGTH);
- *kB = xor (unwrapBKey, wrapKB, EPHY_SYNC_TOKEN_LENGTH);
+ *kB = ephy_sync_crypto_xor (unwrapBKey, wrapKB, EPHY_SYNC_TOKEN_LENGTH);
g_free (bdl);
g_free (ciphertext);
@@ -641,14 +598,12 @@ ephy_sync_crypto_compute_hawk_header (const gchar *url,
const gchar *method,
const gchar *id,
guint8 *key,
- gsize key_length,
+ gsize key_len,
EphySyncCryptoHawkOptions *options)
{
EphySyncCryptoHawkArtifacts *artifacts;
SoupURI *uri;
- gboolean has_options;
- const gchar *hostname;
- const gchar *resource;
+ gchar *resource;
gchar *hash;
gchar *header;
gchar *mac;
@@ -656,92 +611,87 @@ ephy_sync_crypto_compute_hawk_header (const gchar *url,
gchar *payload;
gchar *timestamp;
gint64 ts;
- guint port;
- g_return_val_if_fail (url && strlen (url) > 0, NULL);
- g_return_val_if_fail (method && strlen (method) > 0, NULL);
- g_return_val_if_fail (id && strlen (id) > 0, NULL);
- g_return_val_if_fail (key, NULL);
+ g_return_val_if_fail (url != NULL, NULL);
+ g_return_val_if_fail (method != NULL, NULL);
+ g_return_val_if_fail (id != NULL, NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+
+ ts = ephy_sync_utils_current_time_seconds ();
+ nonce = options && options->nonce ? options->nonce : ephy_sync_crypto_generate_random_hex (6);
+ hash = options ? options->hash : NULL;
+ payload = options ? options->payload : NULL;
+ timestamp = options ? options->timestamp : NULL;
+ uri = soup_uri_new (url);
+ resource = (gchar *) soup_uri_get_path (uri);
- has_options = options != NULL;
- ts = g_get_real_time () / 1000000;
+ if (soup_uri_get_query (uri) != NULL)
+ resource = g_strconcat (resource, "?", soup_uri_get_query (uri), NULL);
- timestamp = has_options ? options->timestamp : NULL;
- if (timestamp) {
+ if (timestamp != NULL) {
gchar *local_time_offset;
gint64 offset;
- local_time_offset = has_options ? options->local_time_offset : NULL;
+ local_time_offset = options ? options->local_time_offset : NULL;
offset = local_time_offset ? g_ascii_strtoll (local_time_offset, NULL, 10) : 0;
-
ts = g_ascii_strtoll (timestamp, NULL, 10) + offset;
}
- nonce = has_options ? options->nonce : NULL;
- nonce = nonce ? nonce : ephy_sync_crypto_generate_random_string (6);
- hash = has_options ? options->hash : NULL;
- payload = has_options ? options->payload : NULL;
-
- uri = soup_uri_new (url);
- g_return_val_if_fail (uri, NULL);
- hostname = soup_uri_get_host (uri);
- port = soup_uri_get_port (uri);
- if (soup_uri_get_query (uri) != NULL)
- resource = g_strdup_printf ("%s?%s", soup_uri_get_path (uri), soup_uri_get_query (uri));
- else
- resource = soup_uri_get_path (uri);
-
- if (!hash && payload) {
- const gchar *content_type;
-
- content_type = has_options ? options->content_type : "text/plain";
- hash = calculate_payload_hash (payload, content_type);
+ if (hash == NULL && payload != NULL) {
+ const gchar *content_type = options ? options->content_type : "text/plain";
+ hash = ephy_sync_crypto_calculate_payload_hash (payload, content_type);
}
- artifacts = ephy_sync_crypto_hawk_artifacts_new (has_options ? options->app : NULL,
- has_options ? options->dlg : NULL,
- has_options ? options->ext : NULL,
+ artifacts = ephy_sync_crypto_hawk_artifacts_new (options ? options->app : NULL,
+ options ? options->dlg : NULL,
+ options ? options->ext : NULL,
hash,
- g_strdup (hostname),
- g_strdup (method),
+ soup_uri_get_host (uri),
+ method,
nonce,
- g_strdup_printf ("%u", port),
- g_strdup (resource),
- g_strdup_printf ("%ld", ts));
+ soup_uri_get_port (uri),
+ resource,
+ ts);
- mac = calculate_mac ("header", key, key_length, artifacts);
+ mac = ephy_sync_crypto_calculate_mac ("header", key, key_len, artifacts);
header = g_strconcat ("Hawk id=\"", id, "\"",
", ts=\"", artifacts->ts, "\"",
", nonce=\"", artifacts->nonce, "\"",
NULL);
- if (artifacts->hash && strlen (artifacts->hash) > 0)
- header = append_token_to_header (header, "hash", artifacts->hash);
+ if (artifacts->hash != NULL && strlen (artifacts->hash) > 0)
+ header = ephy_sync_crypto_append_to_header (header, "hash", artifacts->hash);
- if (artifacts->ext && strlen (artifacts->ext) > 0) {
+ if (artifacts->ext != NULL && strlen (artifacts->ext) > 0) {
gchar *h_ext;
gchar *tmp_ext;
- tmp_ext = find_and_replace_string (artifacts->ext, "\\", "\\\\");
- h_ext = find_and_replace_string (tmp_ext, "\n", "\\n");
- header = append_token_to_header (header, "ext", h_ext);
+ tmp_ext = ephy_sync_utils_find_and_replace (artifacts->ext, "\\", "\\\\");
+ h_ext = ephy_sync_utils_find_and_replace (tmp_ext, "\n", "\\n");
+ header = ephy_sync_crypto_append_to_header (header, "ext", h_ext);
g_free (h_ext);
g_free (tmp_ext);
}
- header = append_token_to_header (header, "mac", mac);
+ header = ephy_sync_crypto_append_to_header (header, "mac", mac);
- if (artifacts->app) {
- header = append_token_to_header (header, "app", artifacts->app);
+ if (artifacts->app != NULL) {
+ header = ephy_sync_crypto_append_to_header (header, "app", artifacts->app);
- if (artifacts->dlg)
- header = append_token_to_header (header, "dlg", artifacts->dlg);
+ if (artifacts->dlg != NULL)
+ header = ephy_sync_crypto_append_to_header (header, "dlg", artifacts->dlg);
}
soup_uri_free (uri);
+ if (options == NULL || options->nonce == NULL)
+ g_free (nonce);
+
+ if (soup_uri_get_query (uri) != NULL)
+ g_free (resource);
+
return ephy_sync_crypto_hawk_header_new (header, artifacts);
}
@@ -760,7 +710,7 @@ ephy_sync_crypto_generate_rsa_key_pair (void)
/* Key sizes below 2048 are considered breakable and should not be used */
retval = rsa_generate_keypair (&public, &private,
- NULL, random_func,
+ NULL, ephy_sync_crypto_random_gen,
NULL, NULL, 2048, 0);
if (retval == 0) {
g_warning ("Failed to generate RSA key pair");
@@ -793,6 +743,10 @@ ephy_sync_crypto_create_assertion (const gchar *certificate,
gsize expected_size;
gsize count;
+ g_return_val_if_fail (certificate != NULL, NULL);
+ g_return_val_if_fail (audience != NULL, NULL);
+ g_return_val_if_fail (keypair != NULL, NULL);
+
expires_at = g_get_real_time () / 1000 + duration * 1000;
body = g_strdup_printf ("{\"exp\": %lu, \"aud\": \"%s\"}", expires_at, audience);
body_b64 = ephy_sync_crypto_base64_urlsafe_encode ((guint8 *) body, strlen (body), TRUE);
@@ -804,7 +758,7 @@ ephy_sync_crypto_create_assertion (const gchar *certificate,
digest = ephy_sync_crypto_decode_hex (digest_hex);
if (rsa_sha256_sign_digest_tr (&keypair->public, &keypair->private,
- NULL, random_func,
+ NULL, ephy_sync_crypto_random_gen,
digest, signature) == 0) {
g_warning ("Failed to sign the message. Giving up.");
goto out;
@@ -820,8 +774,7 @@ ephy_sync_crypto_create_assertion (const gchar *certificate,
}
sig_b64 = ephy_sync_crypto_base64_urlsafe_encode (sig, count, TRUE);
- assertion = g_strdup_printf ("%s~%s.%s.%s",
- certificate, header_b64, body_b64, sig_b64);
+ assertion = g_strdup_printf ("%s~%s.%s.%s", certificate, header_b64, body_b64, sig_b64);
out:
g_free (body);
@@ -838,7 +791,7 @@ out:
}
gchar *
-ephy_sync_crypto_generate_random_string (gsize length)
+ephy_sync_crypto_generate_random_hex (gsize length)
{
FILE *fp;
gsize num_bytes;
@@ -864,63 +817,69 @@ ephy_sync_crypto_generate_random_string (gsize length)
gchar *
ephy_sync_crypto_base64_urlsafe_encode (guint8 *data,
- gsize data_length,
+ gsize data_len,
gboolean strip)
{
- gchar *encoded;
gchar *base64;
- gsize start;
+ gchar *out;
+ gsize start = 0;
gssize end;
- base64 = g_base64_encode (data, data_length);
+ g_return_val_if_fail (data != NULL, NULL);
- if (strip == FALSE) {
- base64_to_base64_urlsafe (base64);
- return base64;
- }
+ base64 = g_base64_encode (data, data_len);
+ end = strlen (base64) - 1;
- /* Strip all the '=' */
- start = 0;
- while (start < strlen (base64) && base64[start] == '=')
- start++;
+ if (strip == TRUE) {
+ while (start < strlen (base64) && base64[start] == '=')
+ start++;
- end = strlen (base64) - 1;
- while (end >= 0 && base64[end] == '=')
- end--;
+ while (end >= 0 && base64[end] == '=')
+ end--;
+ }
- encoded = g_strndup (base64 + start, end - start + 1);
- base64_to_base64_urlsafe (encoded);
+ out = g_strndup (base64 + start, end - start + 1);
+ ephy_sync_crypto_b64_to_b64_urlsafe (out);
g_free (base64);
- return encoded;
+ return out;
}
guint8 *
ephy_sync_crypto_base64_urlsafe_decode (const gchar *text,
- gsize *out_length)
+ gsize *out_len,
+ gboolean fill)
{
- guint8 *decoded;
- gchar *text_copy;
+ guint8 *out;
+ gchar *to_decode;
+ gchar *suffix = NULL;
+
+ g_return_val_if_fail (text != NULL, NULL);
+ g_return_val_if_fail (out_len != NULL, NULL);
- text_copy = g_strdup (text);
- base64_urlsafe_to_base64 (text_copy);
- decoded = g_base64_decode (text_copy, out_length);
+ if (fill == TRUE)
+ suffix = g_strnfill ((4 - strlen (text) % 4) % 4, '=');
- g_free (text_copy);
+ to_decode = g_strconcat (text, suffix, NULL);
+ ephy_sync_crypto_b64_urlsafe_to_b64 (to_decode);
+ out = g_base64_decode (to_decode, out_len);
- return decoded;
+ g_free (suffix);
+ g_free (to_decode);
+
+ return out;
}
guint8 *
ephy_sync_crypto_aes_256 (EphySyncCryptoAES256Mode mode,
const guint8 *key,
const guint8 *data,
- gsize data_length,
- gsize *out_length)
+ gsize data_len,
+ gsize *out_len)
{
struct aes256_ctx aes;
- gsize padded_length;
+ gsize padded_len;
guint8 *padded_data;
guint8 *out;
@@ -928,31 +887,31 @@ ephy_sync_crypto_aes_256 (EphySyncCryptoAES256Mode mode,
g_return_val_if_fail (data != NULL, NULL);
if (mode == AES_256_MODE_DECRYPT)
- g_assert (data_length % AES_BLOCK_SIZE == 0);
+ g_assert (data_len % AES_BLOCK_SIZE == 0);
- padded_length = data_length;
- if (data_length % AES_BLOCK_SIZE != 0)
- padded_length = data_length + (AES_BLOCK_SIZE - data_length % AES_BLOCK_SIZE);
+ padded_len = data_len;
+ if (data_len % AES_BLOCK_SIZE != 0)
+ padded_len = data_len + (AES_BLOCK_SIZE - data_len % AES_BLOCK_SIZE);
- out = g_malloc (padded_length);
- padded_data = g_malloc0 (padded_length);
- memcpy (padded_data, data, data_length);
+ out = g_malloc (padded_len);
+ padded_data = g_malloc0 (padded_len);
+ memcpy (padded_data, data, data_len);
switch (mode) {
case AES_256_MODE_ENCRYPT:
aes256_set_encrypt_key (&aes, key);
- aes256_encrypt (&aes, padded_length, out, padded_data);
+ aes256_encrypt (&aes, padded_len, out, padded_data);
break;
case AES_256_MODE_DECRYPT:
aes256_set_decrypt_key (&aes, key);
- aes256_decrypt (&aes, padded_length, out, padded_data);
+ aes256_decrypt (&aes, padded_len, out, padded_data);
break;
default:
g_assert_not_reached ();
}
- if (out_length != NULL)
- *out_length = padded_length;
+ if (out_len != NULL)
+ *out_len = padded_len;
g_free (padded_data);
@@ -961,12 +920,14 @@ ephy_sync_crypto_aes_256 (EphySyncCryptoAES256Mode mode,
gchar *
ephy_sync_crypto_encode_hex (guint8 *data,
- gsize data_length)
+ gsize data_len)
{
gchar *retval;
gsize length;
- length = data_length == 0 ? EPHY_SYNC_TOKEN_LENGTH : data_length;
+ g_return_val_if_fail (data != NULL, NULL);
+
+ length = data_len == 0 ? EPHY_SYNC_TOKEN_LENGTH : data_len;
retval = g_malloc (length * 2 + 1);
for (gsize i = 0; i < length; i++) {
@@ -982,19 +943,17 @@ ephy_sync_crypto_encode_hex (guint8 *data,
}
guint8 *
-ephy_sync_crypto_decode_hex (const gchar *hex_string)
+ephy_sync_crypto_decode_hex (const gchar *hex)
{
guint8 *retval;
- gsize hex_length;
+ gsize hex_len = strlen (hex);
- hex_length = strlen (hex_string);
- g_return_val_if_fail (hex_length % 2 == 0, NULL);
+ g_return_val_if_fail (hex != NULL, NULL);
+ g_return_val_if_fail (hex_len % 2 == 0, NULL);
- retval = g_malloc (hex_length / 2);
-
- for (gsize i = 0, j = 0; i < hex_length; i += 2, j++) {
- sscanf(hex_string + i, "%2hhx", retval + j);
- }
+ retval = g_malloc (hex_len / 2);
+ for (gsize i = 0, j = 0; i < hex_len; i += 2, j++)
+ sscanf(hex + i, "%2hhx", retval + j);
return retval;
}
diff --git a/src/ephy-sync-crypto.h b/src/ephy-sync-crypto.h
index 480726b..628cb30 100644
--- a/src/ephy-sync-crypto.h
+++ b/src/ephy-sync-crypto.h
@@ -66,73 +66,59 @@ typedef struct {
struct rsa_private_key private;
} EphySyncCryptoRSAKeyPair;
-EphySyncCryptoHawkOptions *ephy_sync_crypto_hawk_options_new (gchar *app,
- gchar *dlg,
- gchar *ext,
- gchar *content_type,
- gchar *hash,
- gchar *local_time_offset,
- gchar *nonce,
- gchar *payload,
- gchar *timestamp);
-
-void ephy_sync_crypto_hawk_options_free (EphySyncCryptoHawkOptions *hawk_options);
-
-void ephy_sync_crypto_hawk_header_free (EphySyncCryptoHawkHeader *hawk_header);
-
-void ephy_sync_crypto_rsa_key_pair_free (EphySyncCryptoRSAKeyPair *keypair);
-
-void ephy_sync_crypto_process_key_fetch_token (const gchar *keyFetchToken,
- guint8 **tokenID,
- guint8 **reqHMACkey,
- guint8 **respHMACkey,
- guint8 **respXORkey);
-
-void ephy_sync_crypto_process_session_token (const gchar *sessionToken,
- guint8 **tokenID,
- guint8 **reqHMACkey,
- guint8 **requestKey);
-
-void ephy_sync_crypto_retrieve_sync_keys (const gchar *bundle,
- guint8 *respHMACkey,
- guint8 *respXORkey,
- guint8 *unwrapBKey,
- guint8 **kA,
- guint8 **kB);
-
-EphySyncCryptoHawkHeader *ephy_sync_crypto_compute_hawk_header (const gchar *url,
- const gchar *method,
- const gchar *id,
- guint8 *key,
- gsize key_length,
- EphySyncCryptoHawkOptions *options);
-
-EphySyncCryptoRSAKeyPair *ephy_sync_crypto_generate_rsa_key_pair (void);
-
-gchar *ephy_sync_crypto_create_assertion (const gchar *certificate,
- const gchar *audience,
- guint64 duration,
- EphySyncCryptoRSAKeyPair *keypair);
-
-gchar *ephy_sync_crypto_generate_random_string (gsize length);
-
-gchar *ephy_sync_crypto_base64_urlsafe_encode (guint8 *data,
- gsize data_length,
- gboolean strip);
-
-guint8 *ephy_sync_crypto_base64_urlsafe_decode (const gchar *text,
- gsize *out_length);
-
-guint8 *ephy_sync_crypto_aes_256 (EphySyncCryptoAES256Mode mode,
- const guint8 *key,
- const guint8 *data,
- gsize data_length,
- gsize *out_length);
-
-gchar *ephy_sync_crypto_encode_hex (guint8 *data,
- gsize data_length);
-
-guint8 *ephy_sync_crypto_decode_hex (const gchar *hex_string);
+EphySyncCryptoHawkOptions *ephy_sync_crypto_hawk_options_new (const gchar *app,
+ const gchar *dlg,
+ const gchar *ext,
+ const gchar *content_type,
+ const gchar *hash,
+ const gchar *local_time_offset,
+ const gchar *nonce,
+ const gchar *payload,
+ const gchar *timestamp);
+void ephy_sync_crypto_hawk_options_free (EphySyncCryptoHawkOptions *options);
+void ephy_sync_crypto_hawk_header_free (EphySyncCryptoHawkHeader *header);
+void ephy_sync_crypto_rsa_key_pair_free (EphySyncCryptoRSAKeyPair *keypair);
+void ephy_sync_crypto_process_key_fetch_token (const gchar *keyFetchToken,
+ guint8 **tokenID,
+ guint8 **reqHMACkey,
+ guint8 **respHMACkey,
+ guint8 **respXORkey);
+void ephy_sync_crypto_process_session_token (const gchar *sessionToken,
+ guint8 **tokenID,
+ guint8 **reqHMACkey,
+ guint8 **requestKey);
+void ephy_sync_crypto_compute_sync_keys (const gchar *bundle,
+ guint8 *respHMACkey,
+ guint8 *respXORkey,
+ guint8 *unwrapBKey,
+ guint8 **kA,
+ guint8 **kB);
+EphySyncCryptoHawkHeader *ephy_sync_crypto_compute_hawk_header (const gchar *url,
+ const gchar *method,
+ const gchar *id,
+ guint8 *key,
+ gsize key_len,
+ EphySyncCryptoHawkOptions *options);
+EphySyncCryptoRSAKeyPair *ephy_sync_crypto_generate_rsa_key_pair (void);
+gchar *ephy_sync_crypto_create_assertion (const gchar *certificate,
+ const gchar *audience,
+ guint64 duration,
+ EphySyncCryptoRSAKeyPair *keypair);
+gchar *ephy_sync_crypto_generate_random_hex (gsize length);
+gchar *ephy_sync_crypto_base64_urlsafe_encode (guint8 *data,
+ gsize data_len,
+ gboolean strip);
+guint8 *ephy_sync_crypto_base64_urlsafe_decode (const gchar *text,
+ gsize *out_len,
+ gboolean fill);
+guint8 *ephy_sync_crypto_aes_256 (EphySyncCryptoAES256Mode mode,
+ const guint8 *key,
+ const guint8 *data,
+ gsize data_len,
+ gsize *out_len);
+gchar *ephy_sync_crypto_encode_hex (guint8 *data,
+ gsize data_len);
+guint8 *ephy_sync_crypto_decode_hex (const gchar *hex_string);
G_END_DECLS
diff --git a/src/ephy-sync-secret.c b/src/ephy-sync-secret.c
index e98c5bb..58603eb 100644
--- a/src/ephy-sync-secret.c
+++ b/src/ephy-sync-secret.c
@@ -63,62 +63,51 @@ store_token_cb (SecretService *service,
}
void
-ephy_sync_secret_forget_all_tokens (void)
+ephy_sync_secret_forget_tokens (void)
{
GHashTable *attributes;
attributes = secret_attributes_build (EPHY_SYNC_TOKEN_SCHEMA, NULL);
- secret_service_clear (NULL,
- EPHY_SYNC_TOKEN_SCHEMA,
- attributes,
- NULL,
- (GAsyncReadyCallback) forget_all_tokens_cb,
- NULL);
+ secret_service_clear (NULL, EPHY_SYNC_TOKEN_SCHEMA, attributes,
+ NULL, (GAsyncReadyCallback) forget_all_tokens_cb, NULL);
g_hash_table_unref (attributes);
}
void
-ephy_sync_secret_load_tokens (EphySyncService *sync_service)
+ephy_sync_secret_load_tokens (EphySyncService *service)
{
SecretItem *secret_item;
SecretValue *secret_value;
GHashTable *attributes;
GError *error = NULL;
GList *matches;
- GList *tmp;
- EphySyncServiceTokenType type;
- const gchar *emailUTF8;
+ EphySyncTokenType type;
+ const gchar *email;
const gchar *value;
gchar *user_email;
- user_email = ephy_sync_service_get_user_email (sync_service);
+ user_email = ephy_sync_service_get_user_email (service);
attributes = secret_attributes_build (EPHY_SYNC_TOKEN_SCHEMA, NULL);
/* Do this synchronously so the tokens will be available immediately */
- matches = secret_service_search_sync (NULL,
- EPHY_SYNC_TOKEN_SCHEMA,
- attributes,
+ matches = secret_service_search_sync (NULL, EPHY_SYNC_TOKEN_SCHEMA, attributes,
SECRET_SEARCH_ALL | SECRET_SEARCH_UNLOCK |
SECRET_SEARCH_LOAD_SECRETS,
- NULL,
- &error);
-
- for (tmp = matches; tmp != NULL; tmp = tmp->next) {
- secret_item = tmp->data;
+ NULL, &error);
+ for (GList *m = matches; m != NULL; m = m->next) {
+ secret_item = m->data;
attributes = secret_item_get_attributes (secret_item);
- emailUTF8 = g_hash_table_lookup (attributes, EMAIL_KEY);
- type = g_ascii_strtoull (g_hash_table_lookup (attributes, TOKEN_TYPE_KEY),
- NULL, 10);
+ email = g_hash_table_lookup (attributes, EMAIL_KEY);
+ type = g_ascii_strtoull (g_hash_table_lookup (attributes, TOKEN_TYPE_KEY), NULL, 10);
secret_value = secret_item_get_secret (secret_item);
value = secret_value_get_text (secret_value);
/* Sanity check */
- if (g_str_equal (emailUTF8, user_email) == FALSE)
+ if (g_strcmp0 (email, user_email) != 0)
continue;
- ephy_sync_service_set_token (sync_service, g_strdup (value), type);
-
+ ephy_sync_service_set_token (service, g_strdup (value), type);
g_hash_table_unref (attributes);
}
@@ -126,22 +115,22 @@ ephy_sync_secret_load_tokens (EphySyncService *sync_service)
}
void
-ephy_sync_secret_store_token (const gchar *emailUTF8,
- gchar *value,
- EphySyncServiceTokenType type)
+ephy_sync_secret_store_token (const gchar *email,
+ gchar *value,
+ EphySyncTokenType type)
{
SecretValue *secret_value;
GHashTable *attributes;
const gchar *name;
gchar *label;
- g_return_if_fail (emailUTF8);
+ g_return_if_fail (email);
g_return_if_fail (value);
- name = ephy_sync_service_token_name_from_type (type);
+ name = ephy_sync_utils_token_name_from_type (type);
secret_value = secret_value_new (value, -1, "text/plain");
attributes = secret_attributes_build (EPHY_SYNC_TOKEN_SCHEMA,
- EMAIL_KEY, emailUTF8,
+ EMAIL_KEY, email,
TOKEN_TYPE_KEY, type,
TOKEN_NAME_KEY, name,
NULL);
@@ -150,15 +139,9 @@ ephy_sync_secret_store_token (const gchar *emailUTF8,
*/
label = g_strdup_printf (_("Token value for %s token"), name);
- secret_service_store (NULL,
- EPHY_SYNC_TOKEN_SCHEMA,
- attributes,
- NULL,
- label,
- secret_value,
- NULL,
- (GAsyncReadyCallback) store_token_cb,
- NULL);
+ secret_service_store (NULL, EPHY_SYNC_TOKEN_SCHEMA, attributes,
+ NULL, label, secret_value, NULL,
+ (GAsyncReadyCallback) store_token_cb, NULL);
g_free (label);
secret_value_unref (secret_value);
diff --git a/src/ephy-sync-secret.h b/src/ephy-sync-secret.h
index 398afd1..cd1e8b5 100644
--- a/src/ephy-sync-secret.h
+++ b/src/ephy-sync-secret.h
@@ -28,19 +28,17 @@ G_BEGIN_DECLS
const SecretSchema *ephy_sync_secret_get_token_schema (void) G_GNUC_CONST;
-#define EMAIL_KEY "email_utf8"
-#define TOKEN_TYPE_KEY "token_type"
-#define TOKEN_NAME_KEY "token_name"
+#define EMAIL_KEY "email_utf8"
+#define TOKEN_TYPE_KEY "token_type"
+#define TOKEN_NAME_KEY "token_name"
#define EPHY_SYNC_TOKEN_SCHEMA (ephy_sync_secret_get_token_schema ())
-void ephy_sync_secret_forget_all_tokens (void);
-
-void ephy_sync_secret_load_tokens (EphySyncService *sync_service);
-
-void ephy_sync_secret_store_token (const gchar *emailUTF8,
- gchar *value,
- EphySyncServiceTokenType type);
+void ephy_sync_secret_forget_tokens (void);
+void ephy_sync_secret_load_tokens (EphySyncService *service);
+void ephy_sync_secret_store_token (const gchar *email,
+ gchar *value,
+ EphySyncTokenType type);
G_END_DECLS
diff --git a/src/ephy-sync-service.c b/src/ephy-sync-service.c
index 49bc630..07ce082 100644
--- a/src/ephy-sync-service.c
+++ b/src/ephy-sync-service.c
@@ -23,41 +23,37 @@
#include "ephy-settings.h"
#include "ephy-sync-crypto.h"
#include "ephy-sync-secret.h"
-#include "ephy-sync-utils.h"
#include <json-glib/json-glib.h>
#include <string.h>
-#define MOZILLA_TOKEN_SERVER_URL "https://token.services.mozilla.com/1.0/sync/1.5"
-#define MOZILLA_FIREFOX_ACCOUNTS_BASE_URL "https://api.accounts.firefox.com/"
-#define MOZILLA_FIREFOX_ACCOUNTS_VERSION "v1/"
-
-#define EMAIL_REGEX "^[a-zA-Z0-9_]([a-zA-Z0-9._]+[a-zA-Z0-9_])?@[a-z0-9.-]+$"
-#define CURRENT_TIME_IN_SECONDS (g_get_real_time () / 1000000)
+#define MOZILLA_TOKEN_SERVER_URL "https://token.services.mozilla.com/1.0/sync/1.5"
+#define MOZILLA_FXA_SERVER_URL "https://api.accounts.firefox.com/v1/"
+#define EMAIL_REGEX "^[a-zA-Z0-9_]([a-zA-Z0-9._]+[a-zA-Z0-9_])?@[a-z0-9.-]+$"
struct _EphySyncService {
- GObject parent_instance;
+ GObject parent_instance;
- SoupSession *soup_session;
+ SoupSession *session;
- gchar *uid;
- gchar *sessionToken;
- gchar *keyFetchToken;
- gchar *unwrapBKey;
- gchar *kA;
- gchar *kB;
+ gchar *uid;
+ gchar *sessionToken;
+ gchar *keyFetchToken;
+ gchar *unwrapBKey;
+ gchar *kA;
+ gchar *kB;
- gchar *user_email;
- gint64 last_auth_at;
+ gchar *user_email;
+ gint64 auth_at;
- gboolean is_locked;
- gchar *storage_endpoint;
- gchar *storage_credentials_id;
- gchar *storage_credentials_key;
- gint64 storage_credentials_expiry_time;
- GQueue *storage_queue;
+ gboolean is_locked;
+ gchar *storage_endpoint;
+ gchar *storage_credentials_id;
+ gchar *storage_credentials_key;
+ gint64 storage_credentials_expiry_time;
+ GQueue *storage_queue;
- gchar *certificate;
+ gchar *certificate;
EphySyncCryptoRSAKeyPair *keypair;
};
@@ -111,74 +107,21 @@ storage_server_request_async_data_free (StorageServerRequestAsyncData *data)
g_slice_free (StorageServerRequestAsyncData, data);
}
-static gchar *
-get_audience_for_url (const gchar *url)
-{
- SoupURI *uri;
- const gchar *scheme;
- const gchar *host;
- gchar *port_str;
- guint port;
- gchar *audience;
-
- uri = soup_uri_new (url);
- g_assert (uri != NULL);
-
- scheme = soup_uri_get_scheme (uri);
- host = soup_uri_get_host (uri);
- port = soup_uri_get_port (uri);
- port_str = g_strdup_printf (":%u", port);
-
- /* Even if the url doesn't contain the port, soup_uri_get_port() will return
- * the default port for the url's scheme so we need to check if the port was
- * really present in the url.
- */
- if (g_strstr_len (url, -1, port_str) != NULL)
- audience = g_strdup_printf ("%s://%s:%u", scheme, host, port);
- else
- audience = g_strdup_printf ("%s://%s", scheme, host);
-
- soup_uri_free (uri);
- g_free (port_str);
-
- return audience;
-}
-
-static guchar *
-base64_parse (const gchar *string,
- gsize *out_len)
-{
- gchar *suffix;
- gchar *full;
- guchar *decoded;
- gsize len;
-
- len = ((4 - strlen (string) % 4) % 4);
- suffix = g_strnfill (len, '=');
- full = g_strconcat (string, suffix, NULL);
- decoded = g_base64_decode (full, out_len);
-
- g_free (suffix);
- g_free (full);
-
- return decoded;
-}
-
static void
destroy_session_response_cb (SoupSession *session,
- SoupMessage *message,
+ SoupMessage *msg,
gpointer user_data)
{
JsonParser *parser;
JsonObject *json;
- if (message->status_code == 200) {
+ if (msg->status_code == 200) {
LOG ("Session destroyed");
return;
}
parser = json_parser_new ();
- json_parser_load_from_data (parser, message->response_body->data, -1, NULL);
+ json_parser_load_from_data (parser, msg->response_body->data, -1, NULL);
json = json_node_get_object (json_parser_get_root (parser));
g_warning ("Failed to destroy session: errno: %ld, errmsg: %s",
@@ -191,6 +134,8 @@ destroy_session_response_cb (SoupSession *session,
static gboolean
ephy_sync_service_storage_credentials_is_expired (EphySyncService *self)
{
+ g_return_val_if_fail (EPHY_IS_SYNC_SERVICE (self), TRUE);
+
if (self->storage_credentials_id == NULL || self->storage_credentials_key == NULL)
return TRUE;
@@ -198,7 +143,7 @@ ephy_sync_service_storage_credentials_is_expired (EphySyncService *self)
return TRUE;
/* Consider a 60 seconds safety interval. */
- return self->storage_credentials_expiry_time < CURRENT_TIME_IN_SECONDS - 60;
+ return self->storage_credentials_expiry_time < ephy_sync_utils_current_time_seconds () - 60;
}
static void
@@ -211,39 +156,33 @@ ephy_sync_service_fxa_hawk_post_async (EphySyncService *self,
SoupSessionCallback callback,
gpointer user_data)
{
- EphySyncCryptoHawkOptions *hawk_options;
- EphySyncCryptoHawkHeader *hawk_header;
- SoupMessage *message;
+ EphySyncCryptoHawkOptions *hoptions;
+ EphySyncCryptoHawkHeader *hheader;
+ SoupMessage *msg;
gchar *url;
const gchar *content_type = "application/json";
- url = g_strdup_printf ("%s%s%s",
- MOZILLA_FIREFOX_ACCOUNTS_BASE_URL,
- MOZILLA_FIREFOX_ACCOUNTS_VERSION,
- endpoint);
- message = soup_message_new (SOUP_METHOD_POST, url);
- soup_message_set_request (message, content_type,
- SOUP_MEMORY_COPY,
+ g_return_if_fail (EPHY_IS_SYNC_SERVICE (self));
+ g_return_if_fail (endpoint != NULL);
+ g_return_if_fail (id != NULL);
+ g_return_if_fail (key != NULL);
+ g_return_if_fail (request_body != NULL);
+
+ url = g_strdup_printf ("%s%s", MOZILLA_FXA_SERVER_URL, endpoint);
+ msg = soup_message_new (SOUP_METHOD_POST, url);
+ soup_message_set_request (msg, content_type, SOUP_MEMORY_COPY,
request_body, strlen (request_body));
- hawk_options = ephy_sync_crypto_hawk_options_new (NULL, NULL, NULL,
- g_strdup (content_type),
- NULL, NULL, NULL,
- g_strdup (request_body),
- NULL);
- hawk_header = ephy_sync_crypto_compute_hawk_header (url, "POST",
- id,
- key, key_length,
- hawk_options);
- soup_message_headers_append (message->request_headers,
- "authorization", hawk_header->header);
- soup_message_headers_append (message->request_headers,
- "content-type", content_type);
- soup_session_queue_message (self->soup_session, message, callback, user_data);
+ 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", id, key, key_length, hoptions);
+ soup_message_headers_append (msg->request_headers, "authorization", hheader->header);
+ soup_message_headers_append (msg->request_headers, "content-type", content_type);
+ soup_session_queue_message (self->session, msg, callback, user_data);
g_free (url);
- ephy_sync_crypto_hawk_options_free (hawk_options);
- ephy_sync_crypto_hawk_header_free (hawk_header);
+ ephy_sync_crypto_hawk_options_free (hoptions);
+ ephy_sync_crypto_hawk_header_free (hheader);
}
static guint
@@ -254,98 +193,87 @@ ephy_sync_service_fxa_hawk_get_sync (EphySyncService *self,
gsize key_length,
JsonNode **node)
{
- EphySyncCryptoHawkHeader *hawk_header;
- SoupMessage *message;
+ EphySyncCryptoHawkHeader *hheader;
+ SoupMessage *msg;
JsonParser *parser;
gchar *url;
- url = g_strdup_printf ("%s%s%s",
- MOZILLA_FIREFOX_ACCOUNTS_BASE_URL,
- MOZILLA_FIREFOX_ACCOUNTS_VERSION,
- endpoint);
- message = soup_message_new (SOUP_METHOD_GET, url);
- hawk_header = ephy_sync_crypto_compute_hawk_header (url, "GET",
- id,
- key, key_length,
- NULL);
- soup_message_headers_append (message->request_headers,
- "authorization", hawk_header->header);
- soup_session_send_message (self->soup_session, message);
+ g_return_val_if_fail (EPHY_IS_SYNC_SERVICE (self), 0);
+ g_return_val_if_fail (endpoint != NULL, 0);
+ g_return_val_if_fail (id != NULL, 0);
+ g_return_val_if_fail (key != NULL, 0);
+
+ url = g_strdup_printf ("%s%s", MOZILLA_FXA_SERVER_URL, endpoint);
+ msg = soup_message_new (SOUP_METHOD_GET, url);
+ hheader = ephy_sync_crypto_compute_hawk_header (url, "GET", id, key, key_length, NULL);
+ soup_message_headers_append (msg->request_headers, "authorization", hheader->header);
+ soup_session_send_message (self->session, msg);
if (node != NULL) {
parser = json_parser_new ();
- json_parser_load_from_data (parser,
- message->response_body->data,
- -1, NULL);
+ json_parser_load_from_data (parser, msg->response_body->data, -1, NULL);
*node = json_node_copy (json_parser_get_root (parser));
g_object_unref (parser);
}
g_free (url);
- ephy_sync_crypto_hawk_header_free (hawk_header);
+ ephy_sync_crypto_hawk_header_free (hheader);
- return message->status_code;
+ return msg->status_code;
}
static void
ephy_sync_service_send_storage_request (EphySyncService *self,
StorageServerRequestAsyncData *data)
{
- EphySyncCryptoHawkOptions *hawk_options = NULL;
- EphySyncCryptoHawkHeader *hawk_header;
- SoupMessage *message;
+ EphySyncCryptoHawkOptions *hoptions = NULL;
+ EphySyncCryptoHawkHeader *hheader;
+ SoupMessage *msg;
gchar *url;
gchar *if_modified_since = NULL;
gchar *if_unmodified_since = NULL;
const gchar *content_type = "application/json";
+ g_return_if_fail (EPHY_IS_SYNC_SERVICE (self));
+ g_return_if_fail (data != NULL);
+
url = g_strdup_printf ("%s/%s", self->storage_endpoint, data->endpoint);
- message = soup_message_new (data->method, url);
+ msg = soup_message_new (data->method, url);
if (data->request_body != NULL) {
- hawk_options = ephy_sync_crypto_hawk_options_new (NULL, NULL, NULL,
- g_strdup (content_type),
- NULL, NULL, NULL,
- g_strdup (data->request_body),
- NULL);
- soup_message_set_request (message, content_type,
- SOUP_MEMORY_COPY,
+ hoptions = ephy_sync_crypto_hawk_options_new (NULL, NULL, NULL, content_type,
+ NULL, NULL, NULL, data->request_body, NULL);
+ soup_message_set_request (msg, content_type, SOUP_MEMORY_COPY,
data->request_body, strlen (data->request_body));
}
- if (g_strcmp0 (data->method, SOUP_METHOD_POST) == 0) {
- soup_message_headers_append (message->request_headers,
- "content-type", content_type);
- }
+ if (g_strcmp0 (data->method, SOUP_METHOD_POST) == 0)
+ soup_message_headers_append (msg->request_headers, "content-type", content_type);
if (data->modified_since >= 0) {
if_modified_since = g_strdup_printf ("%.2lf", data->modified_since);
- soup_message_headers_append (message->request_headers,
- "X-If-Modified-Since", if_modified_since);
+ soup_message_headers_append (msg->request_headers, "X-If-Modified-Since", if_modified_since);
}
if (data->unmodified_since >= 0) {
if_unmodified_since = g_strdup_printf ("%.2lf", data->unmodified_since);
- soup_message_headers_append (message->request_headers,
- "X-If-Unmodified-Since", if_unmodified_since);
+ soup_message_headers_append (msg->request_headers, "X-If-Unmodified-Since", if_unmodified_since);
}
- hawk_header = ephy_sync_crypto_compute_hawk_header (url, data->method,
- self->storage_credentials_id,
- (guint8 *) self->storage_credentials_key,
- strlen (self->storage_credentials_key),
- hawk_options);
- soup_message_headers_append (message->request_headers,
- "authorization", hawk_header->header);
- soup_session_queue_message (self->soup_session, message,
- data->callback, data->user_data);
+ hheader = ephy_sync_crypto_compute_hawk_header (url, data->method, self->storage_credentials_id,
+ (guint8 *) self->storage_credentials_key,
+ strlen (self->storage_credentials_key),
+ hoptions);
+ soup_message_headers_append (msg->request_headers, "authorization", hheader->header);
+ soup_session_queue_message (self->session, msg, data->callback, data->user_data);
- if (hawk_options != NULL)
- ephy_sync_crypto_hawk_options_free (hawk_options);
+ if (hoptions != NULL)
+ ephy_sync_crypto_hawk_options_free (hoptions);
g_free (url);
g_free (if_modified_since);
g_free (if_unmodified_since);
+ ephy_sync_crypto_hawk_header_free (hheader);
storage_server_request_async_data_free (data);
}
@@ -353,34 +281,34 @@ static gboolean
ephy_sync_service_certificate_is_valid (EphySyncService *self,
const gchar *certificate)
{
- SoupURI *uri;
JsonParser *parser;
JsonObject *json;
JsonObject *principal;
+ SoupURI *uri;
gchar **pieces;
gchar *header;
gchar *payload;
- gchar *uid_email;
- const gchar *algorithm;
+ gchar *uid_email = NULL;
+ const gchar *alg;
const gchar *email;
- gsize header_len;
- gsize payload_len;
+ gsize len;
gboolean retval = FALSE;
+ g_return_val_if_fail (EPHY_IS_SYNC_SERVICE (self), FALSE);
g_return_val_if_fail (certificate != NULL, FALSE);
- uri = soup_uri_new (MOZILLA_FIREFOX_ACCOUNTS_BASE_URL);
+ uri = soup_uri_new (MOZILLA_FXA_SERVER_URL);
pieces = g_strsplit (certificate, ".", 0);
- header = (gchar *) base64_parse (pieces[0], &header_len);
- payload = (gchar *) base64_parse (pieces[1], &payload_len);
+ header = (gchar *) ephy_sync_crypto_base64_urlsafe_decode (pieces[0], &len, TRUE);
+ payload = (gchar *) ephy_sync_crypto_base64_urlsafe_decode (pieces[1], &len, TRUE);
parser = json_parser_new ();
json_parser_load_from_data (parser, header, -1, NULL);
json = json_node_get_object (json_parser_get_root (parser));
- algorithm = json_object_get_string_member (json, "alg");
+ alg = json_object_get_string_member (json, "alg");
- if (g_str_equal (algorithm, "RS256") == FALSE) {
- g_warning ("Expected algorithm RS256, found %s. Giving up.", algorithm);
+ if (g_strcmp0 (alg, "RS256") != 0) {
+ g_warning ("Expected algorithm RS256, found %s. Giving up.", alg);
goto out;
}
@@ -388,16 +316,14 @@ ephy_sync_service_certificate_is_valid (EphySyncService *self,
json = json_node_get_object (json_parser_get_root (parser));
principal = json_object_get_object_member (json, "principal");
email = json_object_get_string_member (principal, "email");
- uid_email = g_strdup_printf ("%s@%s",
- self->uid,
- soup_uri_get_host (uri));
+ uid_email = g_strdup_printf ("%s@%s", self->uid, soup_uri_get_host (uri));
- if (g_str_equal (uid_email, email) == FALSE) {
+ if (g_strcmp0 (uid_email, email) != 0) {
g_warning ("Expected email %s, found %s. Giving up.", uid_email, email);
goto out;
}
- self->last_auth_at = json_object_get_int_member (json, "fxa-lastAuthAt");
+ self->auth_at = json_object_get_int_member (json, "fxa-lastAuthAt");
retval = TRUE;
out:
@@ -413,7 +339,7 @@ out:
static void
obtain_storage_credentials_response_cb (SoupSession *session,
- SoupMessage *message,
+ SoupMessage *msg,
gpointer user_data)
{
StorageServerRequestAsyncData *data;
@@ -427,7 +353,7 @@ obtain_storage_credentials_response_cb (SoupSession *session,
service = EPHY_SYNC_SERVICE (data->service);
parser = json_parser_new ();
- json_parser_load_from_data (parser, message->response_body->data, -1, NULL);
+ json_parser_load_from_data (parser, msg->response_body->data, -1, NULL);
json = json_node_get_object (json_parser_get_root (parser));
/* FIXME: Since a new Firefox Account password means a new kB, and a new kB
@@ -436,12 +362,13 @@ obtain_storage_credentials_response_cb (SoupSession *session,
* password since the last time he signed in. If this happens, the user needs
* to be asked to sign in again with the new password.
*/
- if (message->status_code == 200) {
+ if (msg->status_code == 200) {
service->storage_endpoint = g_strdup (json_object_get_string_member (json, "api_endpoint"));
service->storage_credentials_id = g_strdup (json_object_get_string_member (json, "id"));
service->storage_credentials_key = g_strdup (json_object_get_string_member (json, "key"));
- service->storage_credentials_expiry_time = json_object_get_int_member (json, "duration") +
CURRENT_TIME_IN_SECONDS;
- } else if (message->status_code == 401) {
+ service->storage_credentials_expiry_time = json_object_get_int_member (json, "duration") +
+ ephy_sync_utils_current_time_seconds ();
+ } else if (msg->status_code == 401) {
array = json_object_get_array_member (json, "errors");
errors = json_node_get_object (json_array_get_element (array, 0));
g_warning ("Failed to talk to the Token Server: %s: %s",
@@ -452,7 +379,7 @@ obtain_storage_credentials_response_cb (SoupSession *session,
} else {
g_warning ("Failed to talk to the Token Server, status code %u. "
"See https://docs.services.mozilla.com/token/apis.html#error-responses",
- message->status_code);
+ msg->status_code);
storage_server_request_async_data_free (data);
goto out;
}
@@ -467,22 +394,20 @@ static void
ephy_sync_service_obtain_storage_credentials (EphySyncService *self,
gpointer user_data)
{
- SoupMessage *message;
- guint8 *kB = NULL;
- gchar *hashed_kB = NULL;
- gchar *client_state = NULL;
- gchar *audience = NULL;
- gchar *assertion = NULL;
- gchar *authorization = NULL;
+ SoupMessage *msg;
+ guint8 *kB;
+ gchar *hashed_kB;
+ gchar *client_state;
+ gchar *audience;
+ gchar *assertion;
+ gchar *authorization;
+ g_return_if_fail (EPHY_IS_SYNC_SERVICE (self));
g_return_if_fail (self->certificate != NULL);
g_return_if_fail (self->keypair != NULL);
- audience = get_audience_for_url (MOZILLA_TOKEN_SERVER_URL);
- assertion = ephy_sync_crypto_create_assertion (self->certificate,
- audience,
- 5 * 60,
- self->keypair);
+ audience = ephy_sync_utils_make_audience (MOZILLA_TOKEN_SERVER_URL);
+ assertion = ephy_sync_crypto_create_assertion (self->certificate, audience, 300, self->keypair);
g_return_if_fail (assertion != NULL);
kB = ephy_sync_crypto_decode_hex (self->kB);
@@ -490,16 +415,13 @@ ephy_sync_service_obtain_storage_credentials (EphySyncService *self,
client_state = g_strndup (hashed_kB, EPHY_SYNC_TOKEN_LENGTH);
authorization = g_strdup_printf ("BrowserID %s", assertion);
- message = soup_message_new (SOUP_METHOD_GET, MOZILLA_TOKEN_SERVER_URL);
+ msg = soup_message_new (SOUP_METHOD_GET, MOZILLA_TOKEN_SERVER_URL);
/* We need to add the X-Client-State header so that the Token Server will
* recognize accounts that were previously used to sync Firefox data too.
*/
- soup_message_headers_append (message->request_headers,
- "X-Client-State", client_state);
- soup_message_headers_append (message->request_headers,
- "authorization", authorization);
- soup_session_queue_message (self->soup_session, message,
- obtain_storage_credentials_response_cb, user_data);
+ soup_message_headers_append (msg->request_headers, "X-Client-State", client_state);
+ soup_message_headers_append (msg->request_headers, "authorization", authorization);
+ soup_session_queue_message (self->session, msg, obtain_storage_credentials_response_cb, user_data);
g_free (kB);
g_free (hashed_kB);
@@ -511,7 +433,7 @@ ephy_sync_service_obtain_storage_credentials (EphySyncService *self,
static void
obtain_signed_certificate_response_cb (SoupSession *session,
- SoupMessage *message,
+ SoupMessage *msg,
gpointer user_data)
{
StorageServerRequestAsyncData *data;
@@ -524,10 +446,10 @@ obtain_signed_certificate_response_cb (SoupSession *session,
service = EPHY_SYNC_SERVICE (data->service);
parser = json_parser_new ();
- json_parser_load_from_data (parser, message->response_body->data, -1, NULL);
+ json_parser_load_from_data (parser, msg->response_body->data, -1, NULL);
json = json_node_get_object (json_parser_get_root (parser));
- if (message->status_code != 200) {
+ if (msg->status_code != 200) {
g_warning ("FxA server errno: %ld, errmsg: %s",
json_object_get_int_member (json, "errno"),
json_object_get_string_member (json, "message"));
@@ -559,12 +481,13 @@ ephy_sync_service_obtain_signed_certificate (EphySyncService *self,
guint8 *tokenID;
guint8 *reqHMACkey;
guint8 *requestKey;
- gchar *tokenID_h;
+ gchar *tokenID_hex;
gchar *public_key_json;
gchar *request_body;
- gchar *n_str;
- gchar *e_str;
+ gchar *n;
+ gchar *e;
+ g_return_if_fail (EPHY_IS_SYNC_SERVICE (self));
g_return_if_fail (self->sessionToken != NULL);
if (self->keypair != NULL)
@@ -573,39 +496,30 @@ ephy_sync_service_obtain_signed_certificate (EphySyncService *self,
self->keypair = ephy_sync_crypto_generate_rsa_key_pair ();
g_return_if_fail (self->keypair != NULL);
- ephy_sync_crypto_process_session_token (self->sessionToken,
- &tokenID, &reqHMACkey, &requestKey);
- tokenID_h = ephy_sync_crypto_encode_hex (tokenID, 0);
+ ephy_sync_crypto_process_session_token (self->sessionToken, &tokenID, &reqHMACkey, &requestKey);
+ tokenID_hex = ephy_sync_crypto_encode_hex (tokenID, 0);
- n_str = mpz_get_str (NULL, 10, self->keypair->public.n);
- e_str = mpz_get_str (NULL, 10, self->keypair->public.e);
- public_key_json = ephy_sync_utils_build_json_string ("algorithm", "RS",
- "n", n_str,
- "e", e_str,
- NULL);
+ 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 ("algorithm", "RS", "n", n, "e", e, NULL);
/* Duration is the lifetime of the certificate in milliseconds. The FxA server
* limits the duration to 24 hours. For our purposes, a duration of 30 minutes
* will suffice.
*/
request_body = g_strdup_printf ("{\"publicKey\": %s, \"duration\": %d}",
public_key_json, 30 * 60 * 1000);
- ephy_sync_service_fxa_hawk_post_async (self,
- "certificate/sign",
- tokenID_h,
- reqHMACkey,
- EPHY_SYNC_TOKEN_LENGTH,
- request_body,
- obtain_signed_certificate_response_cb,
- user_data);
+ ephy_sync_service_fxa_hawk_post_async (self, "certificate/sign", tokenID_hex,
+ reqHMACkey, EPHY_SYNC_TOKEN_LENGTH, request_body,
+ obtain_signed_certificate_response_cb, user_data);
g_free (tokenID);
g_free (reqHMACkey);
g_free (requestKey);
- g_free (tokenID_h);
+ g_free (tokenID_hex);
g_free (public_key_json);
g_free (request_body);
- g_free (n_str);
- g_free (e_str);
+ g_free (n);
+ g_free (e);
}
static void
@@ -650,10 +564,10 @@ ephy_sync_service_dispose (GObject *object)
{
EphySyncService *self = EPHY_SYNC_SERVICE (object);
- g_clear_object (&self->soup_session);
+ g_clear_object (&self->session);
g_clear_pointer (&self->user_email, g_free);
ephy_sync_service_clear_storage_credentials (self);
- ephy_sync_service_delete_all_tokens (self);
+ ephy_sync_service_clear_tokens (self);
G_OBJECT_CLASS (ephy_sync_service_parent_class)->dispose (object);
}
@@ -672,12 +586,12 @@ ephy_sync_service_init (EphySyncService *self)
{
gchar *email;
- self->soup_session = soup_session_new ();
+ self->session = soup_session_new ();
self->storage_queue = g_queue_new ();
email = g_settings_get_string (EPHY_SETTINGS_MAIN, EPHY_PREFS_SYNC_USER);
- if (g_str_equal (email, "") == FALSE) {
+ if (g_strcmp0 (email, "") != 0) {
if (g_regex_match_simple (EMAIL_REGEX, email, 0, 0) == TRUE) {
ephy_sync_service_set_user_email (self, email);
ephy_sync_secret_load_tokens (self);
@@ -693,36 +607,19 @@ ephy_sync_service_new (void)
return EPHY_SYNC_SERVICE (g_object_new (EPHY_TYPE_SYNC_SERVICE, NULL));
}
-const gchar *
-ephy_sync_service_token_name_from_type (EphySyncServiceTokenType token_type)
-{
- switch (token_type) {
- case TOKEN_UID:
- return "uid";
- case TOKEN_SESSIONTOKEN:
- return "sessionToken";
- case TOKEN_KEYFETCHTOKEN:
- return "keyFetchToken";
- case TOKEN_UNWRAPBKEY:
- return "unwrapBKey";
- case TOKEN_KA:
- return "kA";
- case TOKEN_KB:
- return "kB";
- default:
- g_assert_not_reached ();
- }
-}
-
gboolean
ephy_sync_service_is_signed_in (EphySyncService *self)
{
+ g_return_val_if_fail (EPHY_IS_SYNC_SERVICE (self), FALSE);
+
return self->user_email != NULL;
}
gchar *
ephy_sync_service_get_user_email (EphySyncService *self)
{
+ g_return_val_if_fail (EPHY_IS_SYNC_SERVICE (self), NULL);
+
return self->user_email;
}
@@ -730,14 +627,18 @@ void
ephy_sync_service_set_user_email (EphySyncService *self,
const gchar *email)
{
+ g_return_if_fail (EPHY_IS_SYNC_SERVICE (self));
+
g_free (self->user_email);
self->user_email = g_strdup (email);
}
gchar *
-ephy_sync_service_get_token (EphySyncService *self,
- EphySyncServiceTokenType type)
+ephy_sync_service_get_token (EphySyncService *self,
+ EphySyncTokenType type)
{
+ g_return_val_if_fail (EPHY_IS_SYNC_SERVICE (self), NULL);
+
switch (type) {
case TOKEN_UID:
return self->uid;
@@ -757,10 +658,13 @@ ephy_sync_service_get_token (EphySyncService *self,
}
void
-ephy_sync_service_set_token (EphySyncService *self,
- gchar *value,
- EphySyncServiceTokenType type)
+ephy_sync_service_set_token (EphySyncService *self,
+ gchar *value,
+ EphySyncTokenType type)
{
+ g_return_if_fail (EPHY_IS_SYNC_SERVICE (self));
+ g_return_if_fail (value != NULL);
+
switch (type) {
case TOKEN_UID:
g_free (self->uid);
@@ -792,23 +696,26 @@ ephy_sync_service_set_token (EphySyncService *self,
}
void
-ephy_sync_service_set_and_store_tokens (EphySyncService *self,
- gchar *first_value,
- EphySyncServiceTokenType first_type,
+ephy_sync_service_set_and_store_tokens (EphySyncService *self,
+ gchar *value,
+ EphySyncTokenType type,
...)
{
- EphySyncServiceTokenType type;
- gchar *value;
+ EphySyncTokenType next_type;
+ gchar *next_value;
va_list args;
- ephy_sync_service_set_token (self, first_value, first_type);
- ephy_sync_secret_store_token (self->user_email, first_value, first_type);
+ g_return_if_fail (EPHY_IS_SYNC_SERVICE (self));
+ g_return_if_fail (value != NULL);
+
+ ephy_sync_service_set_token (self, value, type);
+ ephy_sync_secret_store_token (self->user_email, value, type);
- va_start (args, first_type);
- while ((value = va_arg (args, gchar *)) != NULL) {
- type = va_arg (args, EphySyncServiceTokenType);
- ephy_sync_service_set_token (self, value, type);
- ephy_sync_secret_store_token (self->user_email, value, type);
+ va_start (args, type);
+ while ((next_value = va_arg (args, gchar *)) != NULL) {
+ next_type = va_arg (args, EphySyncTokenType);
+ ephy_sync_service_set_token (self, next_value, next_type);
+ ephy_sync_secret_store_token (self->user_email, next_value, next_type);
}
va_end (args);
}
@@ -826,8 +733,10 @@ ephy_sync_service_clear_storage_credentials (EphySyncService *self)
}
void
-ephy_sync_service_delete_all_tokens (EphySyncService *self)
+ephy_sync_service_clear_tokens (EphySyncService *self)
{
+ g_return_if_fail (EPHY_IS_SYNC_SERVICE (self));
+
g_clear_pointer (&self->uid, g_free);
g_clear_pointer (&self->sessionToken, g_free);
g_clear_pointer (&self->keyFetchToken, g_free);
@@ -840,54 +749,43 @@ void
ephy_sync_service_destroy_session (EphySyncService *self,
const gchar *sessionToken)
{
- EphySyncCryptoHawkOptions *hawk_options;
- EphySyncCryptoHawkHeader *hawk_header;
- SoupMessage *message;
+ EphySyncCryptoHawkOptions *hoptions;
+ EphySyncCryptoHawkHeader *hheader;
+ SoupMessage *msg;
guint8 *tokenID;
guint8 *reqHMACkey;
guint8 *requestKey;
- gchar *tokenID_h;
+ gchar *tokenID_hex;
gchar *url;
const gchar *content_type = "application/json";
const gchar *endpoint = "session/destroy";
const gchar *request_body = "{}";
+ g_return_if_fail (EPHY_IS_SYNC_SERVICE (self));
+
if (sessionToken == NULL)
sessionToken = ephy_sync_service_get_token (self, TOKEN_SESSIONTOKEN);
g_return_if_fail (sessionToken != NULL);
- url = g_strdup_printf ("%s%s%s",
- MOZILLA_FIREFOX_ACCOUNTS_BASE_URL,
- MOZILLA_FIREFOX_ACCOUNTS_VERSION,
- endpoint);
- ephy_sync_crypto_process_session_token (sessionToken,
- &tokenID, &reqHMACkey, &requestKey);
- tokenID_h = ephy_sync_crypto_encode_hex (tokenID, 0);
-
- message = soup_message_new (SOUP_METHOD_POST, url);
- soup_message_set_request (message, content_type,
- SOUP_MEMORY_STATIC,
+ url = g_strdup_printf ("%s%s", MOZILLA_FXA_SERVER_URL, endpoint);
+ ephy_sync_crypto_process_session_token (sessionToken, &tokenID, &reqHMACkey, &requestKey);
+ tokenID_hex = ephy_sync_crypto_encode_hex (tokenID, 0);
+
+ msg = soup_message_new (SOUP_METHOD_POST, url);
+ soup_message_set_request (msg, content_type, SOUP_MEMORY_STATIC,
request_body, strlen (request_body));
- hawk_options = ephy_sync_crypto_hawk_options_new (NULL, NULL, NULL,
- g_strdup (content_type),
- NULL, NULL, NULL,
- g_strdup (request_body),
- NULL);
- hawk_header = ephy_sync_crypto_compute_hawk_header (url, "POST",
- tokenID_h,
- reqHMACkey,
- EPHY_SYNC_TOKEN_LENGTH,
- hawk_options);
- soup_message_headers_append (message->request_headers,
- "authorization", hawk_header->header);
- soup_message_headers_append (message->request_headers,
- "content-type", content_type);
- soup_session_queue_message (self->soup_session, message,
- destroy_session_response_cb, NULL);
-
- ephy_sync_crypto_hawk_options_free (hawk_options);
- ephy_sync_crypto_hawk_header_free (hawk_header);
- g_free (tokenID_h);
+ 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,
+ hoptions);
+ soup_message_headers_append (msg->request_headers, "authorization", hheader->header);
+ soup_message_headers_append (msg->request_headers, "content-type", content_type);
+ soup_session_queue_message (self->session, msg, destroy_session_response_cb, NULL);
+
+ ephy_sync_crypto_hawk_options_free (hoptions);
+ ephy_sync_crypto_hawk_header_free (hheader);
+ g_free (tokenID_hex);
g_free (tokenID);
g_free (reqHMACkey);
g_free (requestKey);
@@ -909,20 +807,21 @@ ephy_sync_service_fetch_sync_keys (EphySyncService *self,
guint8 *respXORkey;
guint8 *kA;
guint8 *kB;
- gchar *tokenID_h;
+ gchar *tokenID_hex;
guint status_code;
gboolean retval = FALSE;
+ g_return_val_if_fail (EPHY_IS_SYNC_SERVICE (self), FALSE);
+ g_return_val_if_fail (email != NULL, FALSE);
+ g_return_val_if_fail (keyFetchToken != NULL, FALSE);
+ g_return_val_if_fail (unwrapBKey != NULL, FALSE);
+
unwrapKB = ephy_sync_crypto_decode_hex (unwrapBKey);
ephy_sync_crypto_process_key_fetch_token (keyFetchToken,
- &tokenID, &reqHMACkey,
- &respHMACkey, &respXORkey);
- tokenID_h = ephy_sync_crypto_encode_hex (tokenID, 0);
- status_code = ephy_sync_service_fxa_hawk_get_sync (self,
- "account/keys",
- tokenID_h,
- reqHMACkey,
- EPHY_SYNC_TOKEN_LENGTH,
+ &tokenID, &reqHMACkey, &respHMACkey, &respXORkey);
+ tokenID_hex = ephy_sync_crypto_encode_hex (tokenID, 0);
+ status_code = ephy_sync_service_fxa_hawk_get_sync (self, "account/keys", tokenID_hex,
+ reqHMACkey, EPHY_SYNC_TOKEN_LENGTH,
&node);
json = json_node_get_object (node);
@@ -933,9 +832,9 @@ ephy_sync_service_fetch_sync_keys (EphySyncService *self,
goto out;
}
- ephy_sync_crypto_retrieve_sync_keys (json_object_get_string_member (json, "bundle"),
- respHMACkey, respXORkey, unwrapKB,
- &kA, &kB);
+ ephy_sync_crypto_compute_sync_keys (json_object_get_string_member (json, "bundle"),
+ respHMACkey, respXORkey, unwrapKB,
+ &kA, &kB);
/* Everything is okay, save the tokens. */
ephy_sync_service_set_user_email (self, email);
@@ -951,12 +850,12 @@ ephy_sync_service_fetch_sync_keys (EphySyncService *self,
out:
json_node_free (node);
+ g_free (unwrapKB);
g_free (tokenID);
g_free (reqHMACkey);
g_free (respHMACkey);
g_free (respXORkey);
- g_free (tokenID_h);
- g_free (unwrapKB);
+ g_free (tokenID_hex);
return retval;
}
@@ -973,8 +872,11 @@ ephy_sync_service_send_storage_message (EphySyncService *self,
{
StorageServerRequestAsyncData *data;
- data = storage_server_request_async_data_new (self, endpoint,
- method, request_body,
+ g_return_if_fail (EPHY_IS_SYNC_SERVICE (self));
+ g_return_if_fail (endpoint != NULL);
+ g_return_if_fail (method != NULL);
+
+ data = storage_server_request_async_data_new (self, endpoint, method, request_body,
modified_since, unmodified_since,
callback, user_data);
diff --git a/src/ephy-sync-service.h b/src/ephy-sync-service.h
index 3c5d63e..d0a27f5 100644
--- a/src/ephy-sync-service.h
+++ b/src/ephy-sync-service.h
@@ -19,6 +19,8 @@
#ifndef EPHY_SYNC_SERVICE_H
#define EPHY_SYNC_SERVICE_H
+#include "ephy-sync-utils.h"
+
#include <glib-object.h>
#include <libsoup/soup.h>
@@ -28,50 +30,28 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (EphySyncService, ephy_sync_service, EPHY, SYNC_SERVICE, GObject)
-typedef enum {
- TOKEN_UID,
- TOKEN_SESSIONTOKEN,
- TOKEN_KEYFETCHTOKEN,
- TOKEN_UNWRAPBKEY,
- TOKEN_KA,
- TOKEN_KB
-} EphySyncServiceTokenType;
-
EphySyncService *ephy_sync_service_new (void);
-
-const gchar *ephy_sync_service_token_name_from_type (EphySyncServiceTokenType token_type);
-
gboolean ephy_sync_service_is_signed_in (EphySyncService *self);
-
gchar *ephy_sync_service_get_user_email (EphySyncService *self);
-
void ephy_sync_service_set_user_email (EphySyncService *self,
const gchar *email);
-
-gchar *ephy_sync_service_get_token (EphySyncService *self,
- EphySyncServiceTokenType token_type);
-
-void ephy_sync_service_set_token (EphySyncService *self,
- gchar *token_value,
- EphySyncServiceTokenType token_type);
-
-void ephy_sync_service_set_and_store_tokens (EphySyncService *self,
- gchar *token_value,
- EphySyncServiceTokenType token_type,
+gchar *ephy_sync_service_get_token (EphySyncService *self,
+ EphySyncTokenType type);
+void ephy_sync_service_set_token (EphySyncService *self,
+ gchar *value,
+ EphySyncTokenType type);
+void ephy_sync_service_set_and_store_tokens (EphySyncService *self,
+ gchar *value,
+ EphySyncTokenType type,
...) G_GNUC_NULL_TERMINATED;
-
-void ephy_sync_service_clear_storage_credentials (EphySyncService *self);
-
-void ephy_sync_service_delete_all_tokens (EphySyncService *self);
-
+void ephy_sync_service_clear_storage_credentials (EphySyncService *self);
+void ephy_sync_service_clear_tokens (EphySyncService *self);
void ephy_sync_service_destroy_session (EphySyncService *self,
const gchar *sessionToken);
-
gboolean ephy_sync_service_fetch_sync_keys (EphySyncService *self,
const gchar *email,
const gchar *keyFetchToken,
const gchar *unwrapBKey);
-
void ephy_sync_service_send_storage_message (EphySyncService *self,
gchar *endpoint,
const gchar *method,
@@ -80,7 +60,6 @@ void ephy_sync_service_send_storage_message (EphySyncService
double unmodified_since,
SoupSessionCallback callback,
gpointer user_data);
-
void ephy_sync_service_release_next_storage_message (EphySyncService *self);
G_END_DECLS
diff --git a/src/ephy-sync-utils.c b/src/ephy-sync-utils.c
index c37f885..702fba7 100644
--- a/src/ephy-sync-utils.c
+++ b/src/ephy-sync-utils.c
@@ -19,24 +19,27 @@
#include "config.h"
#include "ephy-sync-utils.h"
+#include <libsoup/soup.h>
+#include <string.h>
+
gchar *
-ephy_sync_utils_build_json_string (const gchar *first_key,
- const gchar *first_value,
+ephy_sync_utils_build_json_string (const gchar *key,
+ const gchar *value,
...)
{
va_list args;
gchar *json;
- gchar *key;
- gchar *value;
+ gchar *next_key;
+ gchar *next_value;
gchar *tmp;
- json = g_strconcat ("{\"", first_key, "\": \"", first_value, "\"", NULL);
- va_start (args, first_value);
+ json = g_strconcat ("{\"", key, "\": \"", value, "\"", NULL);
+ va_start (args, value);
- while ((key = va_arg (args, gchar *)) != NULL) {
- value = va_arg (args, gchar *);
+ while ((next_key = va_arg (args, gchar *)) != NULL) {
+ next_value = va_arg (args, gchar *);
tmp = json;
- json = g_strconcat (json, ", \"", key, "\": \"", value, "\"", NULL);
+ json = g_strconcat (json, ", \"", next_key, "\": \"", next_value, "\"", NULL);
g_free (tmp);
}
@@ -54,3 +57,117 @@ ephy_sync_utils_create_bso_json (const gchar *id,
{
return ephy_sync_utils_build_json_string ("id", id, "payload", payload, NULL);
}
+
+gchar *
+ephy_sync_utils_make_audience (const gchar *url)
+{
+ SoupURI *uri;
+ const gchar *scheme;
+ const gchar *host;
+ gchar *audience;
+ gchar *port;
+
+ g_return_val_if_fail (url != NULL, NULL);
+
+ uri = soup_uri_new (url);
+ scheme = soup_uri_get_scheme (uri);
+ host = soup_uri_get_host (uri);
+ port = g_strdup_printf (":%u", soup_uri_get_port (uri));
+
+ /* Even if the url doesn't contain the port, soup_uri_get_port() will return
+ * the default port for the url's scheme so we need to check if the port was
+ * really present in the url.
+ */
+ if (g_strstr_len (url, -1, port) != NULL)
+ 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;
+}
+
+const gchar *
+ephy_sync_utils_token_name_from_type (EphySyncTokenType type)
+{
+ switch (type) {
+ case TOKEN_UID:
+ return "uid";
+ case TOKEN_SESSIONTOKEN:
+ return "sessionToken";
+ case TOKEN_KEYFETCHTOKEN:
+ return "keyFetchToken";
+ case TOKEN_UNWRAPBKEY:
+ return "unwrapBKey";
+ case TOKEN_KA:
+ return "kA";
+ case TOKEN_KB:
+ return "kB";
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+gchar *
+ephy_sync_utils_find_and_replace (const gchar *src,
+ const gchar *find,
+ const gchar *repl)
+{
+ const gchar *haystack = src;
+ const gchar *needle = NULL;
+ gsize haystack_len = strlen (src);
+ gsize find_len = strlen (find);
+ gsize repl_len = strlen (repl);
+ gsize new_len = 0;
+ gsize skip_len = 0;
+ gchar *out = g_malloc (haystack_len + 1);
+
+ while ((needle = g_strstr_len (haystack, -1, find)) != NULL) {
+ haystack_len += find_len - 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, repl, repl_len);
+ new_len += skip_len + repl_len;
+ haystack = needle + find_len;
+ }
+ strcpy (out + new_len, haystack);
+
+ return out;
+}
+
+guint8 *
+ephy_sync_utils_concatenate_bytes (guint8 *bytes,
+ gsize bytes_len,
+ ...)
+{
+ va_list args;
+ guint8 *next;
+ guint8 *out;
+ gsize next_len;
+ gsize out_len;
+
+ out_len = bytes_len;
+ out = g_malloc (out_len);
+ memcpy (out, bytes, out_len);
+
+ va_start (args, bytes_len);
+ while ((next = va_arg (args, guint8 *)) != NULL) {
+ next_len = va_arg (args, gsize);
+ out = g_realloc (out, out_len + next_len);
+ memcpy (out + out_len, next, next_len);
+ out_len += next_len;
+ }
+
+ va_end (args);
+
+ return out;
+}
+
+gint64
+ephy_sync_utils_current_time_seconds (void)
+{
+ return g_get_real_time () / 1000000;
+}
diff --git a/src/ephy-sync-utils.h b/src/ephy-sync-utils.h
index 8cf72df..2bfc94a 100644
--- a/src/ephy-sync-utils.h
+++ b/src/ephy-sync-utils.h
@@ -21,14 +21,31 @@
#include <glib-object.h>
-G_BEGIN_DECLS
+typedef enum {
+ TOKEN_UID,
+ TOKEN_SESSIONTOKEN,
+ TOKEN_KEYFETCHTOKEN,
+ TOKEN_UNWRAPBKEY,
+ TOKEN_KA,
+ TOKEN_KB
+} EphySyncTokenType;
-gchar *ephy_sync_utils_build_json_string (const gchar *first_key,
- const gchar *first_value,
- ...) G_GNUC_NULL_TERMINATED;
+G_BEGIN_DECLS
-gchar *ephy_sync_utils_create_bso_json (const gchar *id,
- const gchar *payload);
+gchar *ephy_sync_utils_build_json_string (const gchar *key,
+ const gchar *value,
+ ...) G_GNUC_NULL_TERMINATED;
+gchar *ephy_sync_utils_create_bso_json (const gchar *id,
+ const gchar *payload);
+gchar *ephy_sync_utils_make_audience (const gchar *url);
+const gchar *ephy_sync_utils_token_name_from_type (EphySyncTokenType type);
+gchar *ephy_sync_utils_find_and_replace (const gchar *src,
+ const gchar *find,
+ const gchar *repl);
+guint8 *ephy_sync_utils_concatenate_bytes (guint8 *bytes,
+ gsize bytes_len,
+ ...) G_GNUC_NULL_TERMINATED;
+gint64 ephy_sync_utils_current_time_seconds (void);
G_END_DECLS
diff --git a/src/prefs-dialog.c b/src/prefs-dialog.c
index ced3d20..d1e719c 100644
--- a/src/prefs-dialog.c
+++ b/src/prefs-dialog.c
@@ -357,8 +357,8 @@ on_sync_sign_out_button_clicked (GtkWidget *button,
/* Destroy session and delete tokens. */
ephy_sync_service_destroy_session (service, NULL);
ephy_sync_service_clear_storage_credentials (service);
- ephy_sync_service_delete_all_tokens (service);
- ephy_sync_secret_forget_all_tokens ();
+ ephy_sync_service_clear_tokens (service);
+ ephy_sync_secret_forget_tokens ();
ephy_sync_service_set_user_email (service, NULL);
g_settings_set_string (EPHY_SETTINGS_MAIN, EPHY_PREFS_SYNC_USER, "");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]