[epiphany/wip/ephy-sync: 30/52] Implement sign certificate act
- From: Gabriel - Cristian Ivascu <gabrielivascu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [epiphany/wip/ephy-sync: 30/52] Implement sign certificate act
- Date: Tue, 26 Jul 2016 20:22:25 +0000 (UTC)
commit 0d441056e6d150231c5d49391f512f2ac1ecb47b
Author: Gabriel Ivascu <ivascu gabriel59 gmail com>
Date: Mon Jul 18 23:22:17 2016 +0300
Implement sign certificate act
src/ephy-sync-crypto.c | 60 ++++++++++++++++++++++++
src/ephy-sync-crypto.h | 10 ++++
src/ephy-sync-service.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++
src/ephy-sync-service.h | 2 +
4 files changed, 187 insertions(+), 0 deletions(-)
---
diff --git a/src/ephy-sync-crypto.c b/src/ephy-sync-crypto.c
index 37a9743..50c1584 100644
--- a/src/ephy-sync-crypto.c
+++ b/src/ephy-sync-crypto.c
@@ -142,6 +142,19 @@ ephy_sync_crypto_sync_keys_new (guint8 *kA,
return sync_keys;
}
+static EphySyncCryptoRSAKeyPair *
+ephy_sync_crypto_rsa_key_pair_new (struct rsa_public_key public_key,
+ struct rsa_private_key private_key)
+{
+ EphySyncCryptoRSAKeyPair *key_pair;
+
+ key_pair = g_slice_new (EphySyncCryptoRSAKeyPair);
+ key_pair->public_key = public_key;
+ key_pair->private_key = private_key;
+
+ return key_pair;
+}
+
void
ephy_sync_crypto_hawk_options_free (EphySyncCryptoHawkOptions *hawk_options)
{
@@ -227,6 +240,17 @@ ephy_sync_crypto_sync_keys_free (EphySyncCryptoSyncKeys *sync_keys)
g_slice_free (EphySyncCryptoSyncKeys, sync_keys);
}
+void
+ephy_sync_crypto_rsa_key_pair_free (EphySyncCryptoRSAKeyPair *key_pair)
+{
+ g_return_if_fail (key_pair != NULL);
+
+ rsa_public_key_clear (&key_pair->public_key);
+ rsa_private_key_clear (&key_pair->private_key);
+
+ g_slice_free (EphySyncCryptoRSAKeyPair, key_pair);
+}
+
static guint8 *
xor (guint8 *a,
guint8 *b,
@@ -524,6 +548,15 @@ hkdf (guint8 *in,
g_free (prk);
}
+static void
+random_func (void *ctx,
+ gsize length,
+ guint8 *dst)
+{
+ for (gsize i = 0; i < length; i++)
+ dst[i] = g_random_int ();
+}
+
EphySyncCryptoProcessedKFT *
ephy_sync_crypto_process_key_fetch_token (const gchar *keyFetchToken)
{
@@ -765,3 +798,30 @@ ephy_sync_crypto_compute_hawk_header (const gchar *url,
return ephy_sync_crypto_hawk_header_new (header, artifacts);
}
+
+EphySyncCryptoRSAKeyPair *
+ephy_sync_crypto_generate_rsa_key_pair (void)
+{
+ struct rsa_public_key public;
+ struct rsa_private_key private;
+ gint retval;
+
+ rsa_public_key_init (&public);
+ rsa_private_key_init (&private);
+
+ /* The public exponent, usually one of the small Fermat primes 3, 5, 17, 257, 65537 */
+ mpz_set_ui (public.e, 65537);
+
+ /* Key sizes below 2048 are considered breakable and should not be used */
+ retval = rsa_generate_keypair (&public, &private,
+ NULL, random_func,
+ NULL, NULL, 2048, 0);
+ if (retval == 0) {
+ g_warning ("Failed to generate RSA key pair");
+ rsa_public_key_clear (&public);
+ rsa_private_key_clear (&private);
+ return NULL;
+ }
+
+ return ephy_sync_crypto_rsa_key_pair_new (public, private);
+}
diff --git a/src/ephy-sync-crypto.h b/src/ephy-sync-crypto.h
index 33846ad..545eaa2 100644
--- a/src/ephy-sync-crypto.h
+++ b/src/ephy-sync-crypto.h
@@ -20,6 +20,7 @@
#define EPHY_SYNC_CRYPTO_H
#include <glib-object.h>
+#include <nettle/rsa.h>
G_BEGIN_DECLS
@@ -72,6 +73,11 @@ typedef struct {
guint8 *wrapKB;
} EphySyncCryptoSyncKeys;
+typedef struct {
+ struct rsa_public_key public_key;
+ struct rsa_private_key private_key;
+} EphySyncCryptoRSAKeyPair;
+
EphySyncCryptoHawkOptions *ephy_sync_crypto_hawk_options_new (gchar *app,
gchar *dlg,
gchar *ext,
@@ -92,6 +98,8 @@ void ephy_sync_crypto_processed_st_free (EphySyncCr
void ephy_sync_crypto_sync_keys_free (EphySyncCryptoSyncKeys *sync_keys);
+void ephy_sync_crypto_rsa_key_pair_free (EphySyncCryptoRSAKeyPair *key_pair);
+
EphySyncCryptoProcessedKFT *ephy_sync_crypto_process_key_fetch_token (const gchar *keyFetchToken);
EphySyncCryptoProcessedST *ephy_sync_crypto_process_session_token (const gchar *sessionToken);
@@ -108,6 +116,8 @@ EphySyncCryptoHawkHeader *ephy_sync_crypto_compute_hawk_header (const gcha
gsize key_length,
EphySyncCryptoHawkOptions *options);
+EphySyncCryptoRSAKeyPair *ephy_sync_crypto_generate_rsa_key_pair (void);
+
G_END_DECLS
#endif
diff --git a/src/ephy-sync-service.c b/src/ephy-sync-service.c
index 9077a84..d4b78c2 100644
--- a/src/ephy-sync-service.c
+++ b/src/ephy-sync-service.c
@@ -46,6 +46,59 @@ struct _EphySyncService {
G_DEFINE_TYPE (EphySyncService, ephy_sync_service, G_TYPE_OBJECT);
static guint
+synchronous_hawk_post_request (EphySyncService *self,
+ const gchar *endpoint,
+ const gchar *id,
+ guint8 *key,
+ gsize key_length,
+ gchar *request_body,
+ JsonObject **jobject)
+{
+ EphySyncCryptoHawkOptions *hawk_options;
+ EphySyncCryptoHawkHeader *hawk_header;
+ SoupMessage *message;
+ JsonNode *root;
+ gchar *url;
+ const gchar *content_type = "application/json";
+
+ url = g_strdup_printf ("%s%s%s", FXA_BASEURL, FXA_VERSION, endpoint);
+ message = soup_message_new (SOUP_METHOD_POST, url);
+ soup_message_set_request (message, 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_send_message (self->soup_session, message);
+
+ if (jobject != NULL) {
+ json_parser_load_from_data (self->parser,
+ message->response_body->data,
+ -1, NULL);
+ root = json_parser_get_root (self->parser);
+ g_assert (JSON_NODE_HOLDS_OBJECT (root));
+ *jobject = json_node_get_object (root);
+ }
+
+ g_free (url);
+ ephy_sync_crypto_hawk_options_free (hawk_options);
+ ephy_sync_crypto_hawk_header_free (hawk_header);
+
+ return message->status_code;
+}
+
+static guint
synchronous_hawk_get_request (EphySyncService *self,
const gchar *endpoint,
const gchar *id,
@@ -342,3 +395,65 @@ out:
return retval;
}
+
+const gchar *
+ephy_sync_service_sign_certificate (EphySyncService *self)
+{
+ EphySyncCryptoProcessedST *processed_st;
+ EphySyncCryptoRSAKeyPair *kpair;
+ JsonObject *jobject;
+ gchar *sessionToken;
+ gchar *tokenID;
+ gchar *public_key_json;
+ gchar *request_body;
+ gchar *n_str;
+ gchar *e_str;
+ guint status_code;
+ const gchar *certificate = NULL;
+
+ sessionToken = ephy_sync_service_get_token (self, EPHY_SYNC_TOKEN_SESSIONTOKEN);
+ g_return_val_if_fail (sessionToken != NULL, NULL);
+
+ kpair = ephy_sync_crypto_generate_rsa_key_pair ();
+ g_return_val_if_fail (kpair != NULL, NULL);
+
+ processed_st = ephy_sync_crypto_process_session_token (sessionToken);
+ tokenID = ephy_sync_utils_encode_hex (processed_st->tokenID, 0);
+
+ n_str = mpz_get_str (NULL, 10, kpair->public_key.n);
+ e_str = mpz_get_str (NULL, 10, kpair->public_key.e);
+ public_key_json = ephy_sync_utils_build_json_string ("algorithm", "RS",
+ "n", n_str,
+ "e", e_str,
+ NULL);
+ /* The server allows a maximum certificate lifespan of 24 hours == 86400000 ms */
+ request_body = g_strdup_printf ("{\"publicKey\": %s, \"duration\": 86400000}",
+ public_key_json);
+ status_code = synchronous_hawk_post_request (self,
+ "certificate/sign",
+ tokenID,
+ processed_st->reqHMACkey,
+ EPHY_SYNC_TOKEN_LENGTH,
+ request_body,
+ &jobject);
+
+ if (status_code != STATUS_OK) {
+ g_warning ("FxA server errno: %ld, errmsg: %s",
+ json_object_get_int_member (jobject, "errno"),
+ json_object_get_string_member (jobject, "message"));
+ goto out;
+ }
+
+ certificate = json_object_get_string_member (jobject, "cert");
+
+out:
+ ephy_sync_crypto_processed_st_free (processed_st);
+ ephy_sync_crypto_rsa_key_pair_free (kpair);
+ g_free (tokenID);
+ g_free (public_key_json);
+ g_free (request_body);
+ g_free (n_str);
+ g_free (e_str);
+
+ return certificate;
+}
diff --git a/src/ephy-sync-service.h b/src/ephy-sync-service.h
index 17054b6..9e78a4d 100644
--- a/src/ephy-sync-service.h
+++ b/src/ephy-sync-service.h
@@ -58,6 +58,8 @@ gboolean ephy_sync_service_fetch_sync_keys (EphySyncService *self,
const gchar *keyFetchToken,
const gchar *unwrapBKey);
+const gchar *ephy_sync_service_sign_certificate (EphySyncService *self);
+
G_END_DECLS
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]