Add an option to disable cryptographic operations
[bluesky.git] / bluesky / crypto.c
index 89f6b12..2a5bf6e 100644 (file)
@@ -132,6 +132,9 @@ gboolean bluesky_crypt_block_needs_encryption(uint8_t type)
 void bluesky_crypt_block_encrypt(gchar *cloud_block, size_t len,
                                  BlueSkyCryptKeys *keys)
 {
+    if (bluesky_options.disable_crypto)
+        return;
+
     gcry_error_t status;
     gcry_cipher_hd_t handle;
 
@@ -177,7 +180,7 @@ void bluesky_crypt_block_encrypt(gchar *cloud_block, size_t len,
     }
 
     bluesky_crypt_hmac((char *)&header->crypt_iv,
-                       cloud_block + len - (char *)&header->crypt_iv,
+                       cloud_block + len - (char *)&header->crypt_iv - GUINT32_FROM_LE(header->size3),
                        keys->authentication_key,
                        header->crypt_auth);
 
@@ -185,7 +188,8 @@ void bluesky_crypt_block_encrypt(gchar *cloud_block, size_t len,
 }
 
 gboolean bluesky_crypt_block_decrypt(gchar *cloud_block, size_t len,
-                                     BlueSkyCryptKeys *keys)
+                                     BlueSkyCryptKeys *keys,
+                                     gboolean allow_unauth)
 {
     gcry_error_t status;
     uint8_t hmac_check[CRYPTO_HASH_SIZE];
@@ -200,17 +204,29 @@ gboolean bluesky_crypt_block_decrypt(gchar *cloud_block, size_t len,
         g_assert(memcmp(header->magic, CLOUDLOG_MAGIC_ENCRYPTED,
                         sizeof(header->magic)) == 0);
 
+    if (bluesky_options.disable_crypto) {
+        g_assert(encrypted == FALSE);
+        return TRUE;
+    }
+
     if (encrypted != bluesky_crypt_block_needs_encryption(header->type)) {
         g_warning("Encrypted status of item does not match expected!\n");
     }
 
     bluesky_crypt_hmac((char *)&header->crypt_iv,
-                       cloud_block + len - (char *)&header->crypt_iv,
+                       cloud_block + len - (char *)&header->crypt_iv - GUINT32_FROM_LE(header->size3),
                        keys->authentication_key,
                        hmac_check);
     if (memcmp(hmac_check, header->crypt_auth, CRYPTO_HASH_SIZE) != 0) {
-        g_warning("Cloud block HMAC does not match!\n");
-        return FALSE;
+        g_warning("Cloud block HMAC does not match!");
+        if (allow_unauth
+            && (header->type == LOGTYPE_INODE_MAP + '0'
+                || header->type == LOGTYPE_CHECKPOINT + '0'))
+        {
+            g_warning("Allowing unauthenticated data from cleaner");
+        } else {
+            return FALSE;
+        }
     }
 
     if (encrypted) {