[epiphany/wip/sync: 60/86] sync: Get the per-collection sync keys too, if any
- From: Gabriel Ivașcu <gabrielivascu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [epiphany/wip/sync: 60/86] sync: Get the per-collection sync keys too, if any
- Date: Tue, 28 Mar 2017 20:58:57 +0000 (UTC)
commit 7927e7be3c854b35df60f0ef61139c29b5f0b468
Author: Gabriel Ivascu <ivascu gabriel59 gmail com>
Date: Sat Mar 11 01:20:08 2017 +0200
sync: Get the per-collection sync keys too, if any
src/sync/ephy-sync-crypto.c | 51 +++++++++++++++++++++++++++++
src/sync/ephy-sync-crypto.h | 8 ++++
src/sync/ephy-sync-service.c | 73 ++++++++++++++++++-----------------------
src/sync/ephy-sync-utils.c | 8 ----
src/sync/ephy-sync-utils.h | 4 +--
5 files changed, 92 insertions(+), 52 deletions(-)
---
diff --git a/src/sync/ephy-sync-crypto.c b/src/sync/ephy-sync-crypto.c
index 06d51e2..a070f5c 100644
--- a/src/sync/ephy-sync-crypto.c
+++ b/src/sync/ephy-sync-crypto.c
@@ -176,6 +176,57 @@ ephy_sync_crypto_rsa_key_pair_free (SyncCryptoRSAKeyPair *keypair)
g_slice_free (SyncCryptoRSAKeyPair, keypair);
}
+static SyncCryptoKeyBundle *
+ephy_sync_crypto_key_bundle_new (const char *aes_key_hex,
+ const char *hmac_key_hex)
+{
+ SyncCryptoKeyBundle *bundle;
+
+ bundle = g_slice_new (SyncCryptoKeyBundle);
+ bundle->aes_key_hex = g_strdup (aes_key_hex);
+ bundle->hmac_key_hex = g_strdup (hmac_key_hex);
+
+ return bundle;
+}
+
+SyncCryptoKeyBundle *
+ephy_sync_crypto_key_bundle_from_array (JsonArray *array)
+{
+ SyncCryptoKeyBundle *bundle;
+ char *aes_key_hex;
+ char *hmac_key_hex;
+ guint8 *aes_key;
+ guint8 *hmac_key;
+ gsize len;
+
+ g_return_val_if_fail (array, NULL);
+ g_return_val_if_fail (json_array_get_length (array) == 2, NULL);
+
+ 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);
+ bundle = ephy_sync_crypto_key_bundle_new (aes_key_hex, hmac_key_hex);
+
+ g_free (aes_key);
+ g_free (hmac_key);
+ g_free (aes_key_hex);
+ g_free (hmac_key_hex);
+
+ return bundle;
+}
+
+void
+ephy_sync_crypto_key_bundle_free (SyncCryptoKeyBundle *bundle)
+{
+ g_return_if_fail (bundle);
+
+ g_free (bundle->aes_key_hex);
+ g_free (bundle->hmac_key_hex);
+
+ g_slice_free (SyncCryptoKeyBundle, bundle);
+}
+
static char *
ephy_sync_crypto_kw (const char *name)
{
diff --git a/src/sync/ephy-sync-crypto.h b/src/sync/ephy-sync-crypto.h
index 334bf71..a7e0b85 100644
--- a/src/sync/ephy-sync-crypto.h
+++ b/src/sync/ephy-sync-crypto.h
@@ -21,6 +21,7 @@
#pragma once
#include <glib-object.h>
+#include <json-glib/json-glib.h>
#include <nettle/rsa.h>
G_BEGIN_DECLS
@@ -67,6 +68,11 @@ typedef struct {
struct rsa_private_key private;
} SyncCryptoRSAKeyPair;
+typedef struct {
+ char *aes_key_hex;
+ char *hmac_key_hex;
+} SyncCryptoKeyBundle;
+
SyncCryptoHawkOptions *ephy_sync_crypto_hawk_options_new (const char *app,
const char *dlg,
const char *ext,
@@ -79,6 +85,8 @@ SyncCryptoHawkOptions *ephy_sync_crypto_hawk_options_new (const char
void ephy_sync_crypto_hawk_options_free (SyncCryptoHawkOptions *options);
void ephy_sync_crypto_hawk_header_free (SyncCryptoHawkHeader *header);
void ephy_sync_crypto_rsa_key_pair_free (SyncCryptoRSAKeyPair *keypair);
+SyncCryptoKeyBundle *ephy_sync_crypto_key_bundle_from_array (JsonArray *array);
+void ephy_sync_crypto_key_bundle_free (SyncCryptoKeyBundle *bundle);
void ephy_sync_crypto_process_key_fetch_token (const char *keyFetchToken,
guint8 **tokenID,
guint8 **reqHMACkey,
diff --git a/src/sync/ephy-sync-service.c b/src/sync/ephy-sync-service.c
index 759fde1..9103bde 100644
--- a/src/sync/ephy-sync-service.c
+++ b/src/sync/ephy-sync-service.c
@@ -52,8 +52,7 @@ struct _EphySyncService {
char *uid;
char *sessionToken;
char *kB;
- char *default_aes_key;
- char *default_hmac_key;
+ GHashTable *key_bundles;
char *user_email;
double sync_time;
@@ -614,6 +613,7 @@ ephy_sync_service_finalize (GObject *object)
ephy_sync_crypto_rsa_key_pair_free (self->keypair);
g_queue_free_full (self->storage_queue, (GDestroyNotify) storage_server_request_async_data_free);
+ g_hash_table_destroy (self->key_bundles);
G_OBJECT_CLASS (ephy_sync_service_parent_class)->finalize (object);
}
@@ -676,6 +676,8 @@ ephy_sync_service_init (EphySyncService *self)
self->session = soup_session_new ();
self->storage_queue = g_queue_new ();
+ self->key_bundles = g_hash_table_new_full (g_str_hash, g_str_equal,
+ NULL, (GDestroyNotify)ephy_sync_crypto_key_bundle_free);
settings = ephy_embed_prefs_get_settings ();
user_agent = webkit_settings_get_user_agent (settings);
@@ -759,10 +761,6 @@ ephy_sync_service_get_token (EphySyncService *self,
return self->sessionToken;
case TOKEN_KB:
return self->kB;
- case TOKEN_DEFAULT_AES_KEY:
- return self->default_aes_key;
- case TOKEN_DEFAULT_HMAC_KEY:
- return self->default_hmac_key;
default:
g_assert_not_reached ();
}
@@ -789,14 +787,6 @@ ephy_sync_service_set_token (EphySyncService *self,
g_free (self->kB);
self->kB = g_strdup (value);
break;
- case TOKEN_DEFAULT_AES_KEY:
- g_free (self->default_aes_key);
- self->default_aes_key = g_strdup (value);
- break;
- case TOKEN_DEFAULT_HMAC_KEY:
- g_free (self->default_hmac_key);
- self->default_hmac_key = g_strdup (value);
- break;
default:
g_assert_not_reached ();
}
@@ -822,8 +812,6 @@ ephy_sync_service_clear_tokens (EphySyncService *self)
g_clear_pointer (&self->uid, g_free);
g_clear_pointer (&self->sessionToken, g_free);
g_clear_pointer (&self->kB, g_free);
- g_clear_pointer (&self->default_aes_key, g_free);
- g_clear_pointer (&self->default_hmac_key, g_free);
}
static void
@@ -904,27 +892,26 @@ ephy_sync_service_report_sign_in_error (EphySyncService *self,
}
static void
-obtain_default_sync_keys_cb (SoupSession *session,
- SoupMessage *msg,
- gpointer user_data)
+obtain_sync_key_bundles (SoupSession *session,
+ SoupMessage *msg,
+ gpointer user_data)
{
EphySyncService *service;
JsonParser *parser;
JsonObject *json;
+ JsonObject *collections;
+ JsonNode *node;
JsonArray *array;
+ JsonObjectIter iter;
const char *ciphertext_b64;
const char *iv_b64;
const char *hmac;
+ const char *member;
char *payload;
char *record;
- char *default_aes_key_hex;
- char *default_hmac_key_hex;
guint8 *kB;
guint8 *aes_key;
guint8 *hmac_key;
- guint8 *default_aes_key;
- guint8 *default_hmac_key;
- gsize len;
service = ephy_shell_get_sync_service (ephy_shell_get_default ());
@@ -953,30 +940,33 @@ obtain_default_sync_keys_cb (SoupSession *session,
/* Under no circumstances should a client try to decrypt a record if the HMAC
* verification fails. If the verification is successful, proceed to decrypt
* the record and retrieve the default sync keys. Otherwise, signal the error
- * to the user.*/
+ * to the user. */
if (!ephy_sync_crypto_sha256_hmac_is_valid (ciphertext_b64, hmac_key, hmac)) {
g_warning ("Failed to verify the HMAC value of the crypto/keys record");
} else {
record = ephy_sync_crypto_decrypt_record (ciphertext_b64, iv_b64, aes_key);
json_parser_load_from_data (parser, record, -1, NULL);
json = json_node_get_object (json_parser_get_root (parser));
- array = json_object_get_array_member (json, "default");
- /* TODO: Handle the case when the decrypted record has a non-empty "collections" member.
- * https://github.com/michielbdejong/fxsync-webcrypto/issues/19 */
-
- default_aes_key = g_base64_decode (json_array_get_string_element (array, 0), &len);
- default_hmac_key = g_base64_decode (json_array_get_string_element (array, 1), &len);
- default_aes_key_hex = ephy_sync_crypto_encode_hex (default_aes_key, 0);
- default_hmac_key_hex = ephy_sync_crypto_encode_hex (default_hmac_key, 0);
- ephy_sync_service_set_token (service, default_aes_key_hex, TOKEN_DEFAULT_AES_KEY);
- ephy_sync_service_set_token (service, default_hmac_key_hex, TOKEN_DEFAULT_HMAC_KEY);
+ /* Get the default key bundle. This is always present. */
+ array = json_object_get_array_member (json, "default");
+ g_hash_table_insert (service->key_bundles,
+ (char *)"default",
+ ephy_sync_crypto_key_bundle_from_array (array));
+
+ /* Get the per-collection key bundles, if any. */
+ collections = json_object_get_object_member (json, "collections");
+ json_object_iter_init (&iter, collections);
+ while (json_object_iter_next (&iter, &member, &node)) {
+ if (JSON_NODE_HOLDS_ARRAY (node)) {
+ array = json_node_get_array (node);
+ g_hash_table_insert (service->key_bundles,
+ (char *)member,
+ ephy_sync_crypto_key_bundle_from_array (array));
+ }
+ }
g_free (record);
- g_free (default_aes_key);
- g_free (default_hmac_key);
- g_free (default_aes_key_hex);
- g_free (default_hmac_key_hex);
}
g_free (payload);
@@ -990,13 +980,14 @@ out:
}
static void
-ephy_sync_service_obtain_default_sync_keys (EphySyncService *self)
+ephy_sync_service_obtain_sync_key_bundles (EphySyncService *self)
{
g_assert (EPHY_IS_SYNC_SERVICE (self));
+ g_hash_table_remove_all (self->key_bundles);
ephy_sync_service_queue_storage_request (self, "storage/crypto/keys",
SOUP_METHOD_GET, NULL, -1, -1,
- obtain_default_sync_keys_cb, NULL);
+ obtain_sync_key_bundles, NULL);
}
static void
diff --git a/src/sync/ephy-sync-utils.c b/src/sync/ephy-sync-utils.c
index ca60d5f..73b17d4 100644
--- a/src/sync/ephy-sync-utils.c
+++ b/src/sync/ephy-sync-utils.c
@@ -101,10 +101,6 @@ ephy_sync_utils_token_name_from_type (EphySyncTokenType type)
return "sessionToken";
case TOKEN_KB:
return "kB";
- case TOKEN_DEFAULT_AES_KEY:
- return "defaultAESKey";
- case TOKEN_DEFAULT_HMAC_KEY:
- return "defaultHMACKey";
default:
g_assert_not_reached ();
}
@@ -119,10 +115,6 @@ ephy_sync_utils_token_type_from_name (const char *name)
return TOKEN_SESSIONTOKEN;
} else if (!g_strcmp0 (name, "kB")) {
return TOKEN_KB;
- } else if (!g_strcmp0 (name, "defaultAESKey")) {
- return TOKEN_DEFAULT_AES_KEY;
- } else if (!g_strcmp0 (name, "defaultHMACKey")) {
- return TOKEN_DEFAULT_HMAC_KEY;
} else {
g_assert_not_reached ();
}
diff --git a/src/sync/ephy-sync-utils.h b/src/sync/ephy-sync-utils.h
index 4da216b..10340a8 100644
--- a/src/sync/ephy-sync-utils.h
+++ b/src/sync/ephy-sync-utils.h
@@ -25,9 +25,7 @@
typedef enum {
TOKEN_UID,
TOKEN_SESSIONTOKEN,
- TOKEN_KB,
- TOKEN_DEFAULT_AES_KEY,
- TOKEN_DEFAULT_HMAC_KEY
+ TOKEN_KB
} EphySyncTokenType;
G_BEGIN_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]