#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);
uint64_t next_inum; /* Next available inode for allocation */
BlueSkyStore *store;
-
- uint8_t *encryption_key;
} BlueSkyFS;
/* Inode number of the root directory. */
*/
#include <stdint.h>
+#include <assert.h>
#include <errno.h>
#include <pthread.h>
#include <glib.h>
#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. */
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;
/* 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;
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. */
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);
block->type = BLUESKY_BLOCK_REF;
g_checksum_free(csum);
- bluesky_string_unref(data);
+ //bluesky_string_unref(data);
}
/* Simple in-memory data store for test purposes. */
typedef struct {
S3BucketContext bucket;
+ uint8_t encryption_key[CRYPTO_KEY_SIZE];
} S3Store;
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;
}
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);
}
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;
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 = {
BlueSkyFS *fs;
BlueSkyStore *store;
-static uint8_t filesystem_key[16];
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);