Move encryption into S3 backend.
authorMichael Vrable <mvrable@cs.ucsd.edu>
Tue, 3 Nov 2009 00:11:34 +0000 (16:11 -0800)
committerMichael Vrable <mvrable@cs.ucsd.edu>
Tue, 3 Nov 2009 00:11:34 +0000 (16:11 -0800)
bluesky/bluesky.h
bluesky/crypto.c
bluesky/file.c
bluesky/s3store.c
nfs3/nfsd.c

index 140310b..7408849 100644 (file)
@@ -39,6 +39,7 @@ BlueSkyRCStr *bluesky_string_dup(BlueSkyRCStr *string);
 #define CRYPTO_KEY_SIZE   16
 
 void bluesky_crypt_init();
+void bluesky_crypt_hash_key(const char *keystr, uint8_t *out);
 void bluesky_crypt_random_bytes(guchar *buf, gint len);
 BlueSkyRCStr *bluesky_crypt_encrypt(BlueSkyRCStr *in, const uint8_t *key);
 BlueSkyRCStr *bluesky_crypt_decrypt(BlueSkyRCStr *in, const uint8_t *key);
@@ -94,8 +95,6 @@ typedef struct {
     uint64_t next_inum;         /* Next available inode for allocation */
 
     BlueSkyStore *store;
-
-    uint8_t *encryption_key;
 } BlueSkyFS;
 
 /* Inode number of the root directory. */
index c40c15c..6981f45 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <stdint.h>
+#include <assert.h>
 #include <errno.h>
 #include <pthread.h>
 #include <glib.h>
@@ -15,8 +16,6 @@
 
 #include "bluesky-private.h"
 
-static int DISABLE_CRYPTO = 1;
-
 /* Cryptographic operations.  The rest of the BlueSky code merely calls into
  * the functions in this file, so this is the only point where we interface
  * with an external cryptographic library. */
@@ -43,14 +42,25 @@ void bluesky_crypt_random_bytes(guchar *buf, gint len)
     gcry_randomize(buf, len, GCRY_STRONG_RANDOM);
 }
 
+/* Hash a string down to an encryption key. */
+void bluesky_crypt_hash_key(const char *keystr, uint8_t *out)
+{
+    guint8 raw_csum[32];
+    gsize csum_len = sizeof(raw_csum);
+
+    assert(CRYPTO_KEY_SIZE == 16);
+
+    GChecksum *csum = g_checksum_new(G_CHECKSUM_SHA256);
+    g_checksum_update(csum, keystr, strlen(keystr));
+    g_checksum_get_digest(csum, raw_csum, &csum_len);
+    g_checksum_free(csum);
+
+    memcpy(out, raw_csum, CRYPTO_KEY_SIZE);
+}
+
 /* Encrypt a data block. */
 BlueSkyRCStr *bluesky_crypt_encrypt(BlueSkyRCStr *in, const uint8_t *key)
 {
-    if (DISABLE_CRYPTO) {
-        bluesky_string_ref(in);
-        return in;
-    }
-
     gcry_error_t status;
     gcry_cipher_hd_t handle;
 
@@ -91,11 +101,6 @@ BlueSkyRCStr *bluesky_crypt_encrypt(BlueSkyRCStr *in, const uint8_t *key)
 /* Decrypt a data block. */
 BlueSkyRCStr *bluesky_crypt_decrypt(BlueSkyRCStr *in, const uint8_t *key)
 {
-    if (DISABLE_CRYPTO) {
-        bluesky_string_ref(in);
-        return in;
-    }
-
     gcry_error_t status;
     gcry_cipher_hd_t handle;
 
index fa4705a..607d611 100644 (file)
@@ -157,9 +157,8 @@ void bluesky_block_fetch(BlueSkyFS *fs, BlueSkyBlock *block)
     BlueSkyRCStr *string = bluesky_store_get(fs->store, block->ref);
 
     bluesky_string_unref(block->data);
-    block->data = bluesky_crypt_decrypt(string, fs->encryption_key);
+    block->data = string;
     block->type = BLUESKY_BLOCK_CACHED;
-    bluesky_string_unref(string);
 }
 
 /* Write the given block to cloud-backed storage and mark it clean. */
@@ -169,7 +168,6 @@ void bluesky_block_flush(BlueSkyFS *fs, BlueSkyBlock *block)
         return;
 
     BlueSkyRCStr *data = block->data;
-    data = bluesky_crypt_encrypt(data, fs->encryption_key);
 
     GChecksum *csum = g_checksum_new(G_CHECKSUM_SHA256);
     g_checksum_update(csum, data->data, data->len);
@@ -185,5 +183,5 @@ void bluesky_block_flush(BlueSkyFS *fs, BlueSkyBlock *block)
     block->type = BLUESKY_BLOCK_REF;
 
     g_checksum_free(csum);
-    bluesky_string_unref(data);
+    //bluesky_string_unref(data);
 }
index f85a252..3f4fb16 100644 (file)
@@ -19,6 +19,7 @@
 /* Simple in-memory data store for test purposes. */
 typedef struct {
     S3BucketContext bucket;
+    uint8_t encryption_key[CRYPTO_KEY_SIZE];
 } S3Store;
 
 static gpointer s3store_new()
@@ -30,8 +31,16 @@ static gpointer s3store_new()
     store->bucket.accessKeyId = getenv("AWS_ACCESS_KEY_ID");
     store->bucket.secretAccessKey = getenv("AWS_SECRET_ACCESS_KEY");
 
-    g_print("Initializing S3 with bucket %s, access key %s\n",
-            store->bucket.bucketName, store->bucket.accessKeyId);
+    const char *key = getenv("BLUESKY_KEY");
+    if (key == NULL) {
+        g_error("Encryption key not defined; please set BLUESKY_KEY environment variable");
+        exit(1);
+    }
+
+    bluesky_crypt_hash_key(key, store->encryption_key);
+
+    g_print("Initializing S3 with bucket %s, access key %s, encryption key %s\n",
+            store->bucket.bucketName, store->bucket.accessKeyId, key);
 
     return store;
 }
@@ -82,8 +91,8 @@ static void s3store_response_callback(S3Status status,
                                const S3ErrorDetails *errorDetails,
                                void *callbackData)
 {
-    g_print("S3 operation complete, status=%s\n",
-            S3_get_status_name(status));
+    g_print("S3 operation complete, status=%s, now=%ld\n",
+            S3_get_status_name(status), bluesky_now_hires());
     if (errorDetails != NULL) {
         g_print("  Error message: %s\n", errorDetails->message);
     }
@@ -106,15 +115,20 @@ static BlueSkyRCStr *s3store_get(gpointer s, const gchar *key)
     S3_get_object(&store->bucket, key, NULL, 0, 0, NULL,
                   &handler, &info);
 
-    return bluesky_string_new(info.buf, BLUESKY_BLOCK_SIZE);
+    BlueSkyRCStr *raw, *decrypted;
+    raw = bluesky_string_new(info.buf, BLUESKY_BLOCK_SIZE);
+    decrypted = bluesky_crypt_decrypt(raw, store->encryption_key);
+    bluesky_string_unref(raw);
+    return decrypted;
 }
 
 static void s3store_put(gpointer s, const gchar *key, BlueSkyRCStr *val)
 {
     S3Store *store = (S3Store *)s;
+    BlueSkyRCStr *encrypted = bluesky_crypt_encrypt(val, store->encryption_key);
 
     struct put_info info;
-    info.val = val;
+    info.val = encrypted;
     info.offset = 0;
 
     struct S3PutObjectHandler handler;
@@ -122,9 +136,11 @@ static void s3store_put(gpointer s, const gchar *key, BlueSkyRCStr *val)
     handler.responseHandler.completeCallback = s3store_response_callback;
     handler.putObjectDataCallback = s3store_put_handler;
 
-    g_print("Starting store of %s to S3...\n", key);
-    S3_put_object(&store->bucket, key, val->len, NULL, NULL,
+    g_print("Starting store of %s to S3 at %ld...\n", key, bluesky_now_hires());
+    S3_put_object(&store->bucket, key, encrypted->len, NULL, NULL,
                   &handler, &info);
+
+    /* TODO: unref encrypted */
 }
 
 static BlueSkyStoreImplementation store_impl = {
index 727011d..e4beac1 100644 (file)
@@ -25,7 +25,6 @@ void register_rpc();
 
 BlueSkyFS *fs;
 BlueSkyStore *store;
-static uint8_t filesystem_key[16];
 
 int main(int argc, char *argv[])
 {
@@ -33,16 +32,8 @@ int main(int argc, char *argv[])
     bluesky_init();
     register_rpc();
 
-    bluesky_crypt_random_bytes(filesystem_key, sizeof(filesystem_key));
-    printf("Filesystem key: ");
-    for (i = 0; i < sizeof(filesystem_key); i++) {
-        printf("%02x", filesystem_key[i]);
-    }
-    printf("\n");
-
     store = bluesky_store_new("file");
     fs = bluesky_init_fs("export", store);
-    fs->encryption_key = filesystem_key;
 
     BlueSkyInode *root;
     root = bluesky_get_inode(fs, BLUESKY_ROOT_INUM);