From 3cacf63eaac24de35deb96e00570d4b780d39f72 Mon Sep 17 00:00:00 2001 From: Jeremy Lakeman Date: Mon, 7 Mar 2016 14:34:53 +1030 Subject: [PATCH] Add sqlite column for the hash of the manifest (before any signatures) --- rhizome.h | 2 +- rhizome_bundle.c | 4 ++-- rhizome_crypto.c | 4 ++-- rhizome_database.c | 33 ++++++++++++++++++++++----------- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/rhizome.h b/rhizome.h index 50e042d6..95a050f9 100644 --- a/rhizome.h +++ b/rhizome.h @@ -237,7 +237,7 @@ typedef struct rhizome_manifest size_t manifest_body_bytes; size_t manifest_all_bytes; unsigned char manifestdata[MAX_MANIFEST_BYTES]; - unsigned char manifesthash[crypto_hash_sha512_BYTES]; + rhizome_filehash_t manifesthash; } rhizome_manifest; diff --git a/rhizome_bundle.c b/rhizome_bundle.c index 4e3840cd..06ad089c 100644 --- a/rhizome_bundle.c +++ b/rhizome_bundle.c @@ -428,7 +428,7 @@ int rhizome_manifest_verify(rhizome_manifest *m) if (m->manifest_body_bytes == m->manifest_all_bytes) assert(m->manifestdata[m->manifest_body_bytes - 1] == '\0'); // Hash the body - crypto_hash_sha512(m->manifesthash, m->manifestdata, m->manifest_body_bytes); + crypto_hash_sha512(m->manifesthash.binary, m->manifestdata, m->manifest_body_bytes); // Read signature blocks unsigned ofs = m->manifest_body_bytes; while (ofs < m->manifest_all_bytes) { @@ -1359,7 +1359,7 @@ static struct rhizome_bundle_result rhizome_manifest_selfsign(rhizome_manifest * assert(m->manifest_body_bytes == m->manifest_all_bytes); // no signature yet if (!m->haveSecret) return rhizome_bundle_result_static(RHIZOME_BUNDLE_STATUS_READONLY, "Missing bundle secret"); - crypto_hash_sha512(m->manifesthash, m->manifestdata, m->manifest_body_bytes); + crypto_hash_sha512(m->manifesthash.binary, m->manifestdata, m->manifest_body_bytes); rhizome_signature sig; if (rhizome_sign_hash(m, &sig) == -1) return rhizome_bundle_result_static(RHIZOME_BUNDLE_STATUS_ERROR, "rhizome_sign_hash() failed"); diff --git a/rhizome_crypto.c b/rhizome_crypto.c index 837028ad..fbad7e43 100644 --- a/rhizome_crypto.c +++ b/rhizome_crypto.c @@ -470,7 +470,7 @@ int rhizome_sign_hash_with_key(rhizome_manifest *m,const unsigned char *sk, { IN(); unsigned char signatureBuffer[crypto_sign_edwards25519sha512batch_BYTES + crypto_hash_sha512_BYTES]; - unsigned char *hash = m->manifesthash; + unsigned char *hash = m->manifesthash.binary; unsigned long long sigLen = 0; int mLen = crypto_hash_sha512_BYTES; int r = crypto_sign_edwards25519sha512batch(signatureBuffer, &sigLen, &hash[0], mLen, sk); @@ -568,7 +568,7 @@ int rhizome_manifest_extract_signature(rhizome_manifest *m, unsigned *ofs) { assert(len == 97); /* Reconstitute signature block */ - int r = rhizome_manifest_lookup_signature_validity(m->manifesthash, sig + 1, 96); + int r = rhizome_manifest_lookup_signature_validity(m->manifesthash.binary, sig + 1, 96); if (r) { WARN("Signature verification failed"); RETURN(4); diff --git a/rhizome_database.c b/rhizome_database.c index 371cdc2e..6e5f080f 100644 --- a/rhizome_database.c +++ b/rhizome_database.c @@ -231,6 +231,8 @@ int rhizome_opendb() if (version<1){ /* Create tables as required */ + // Note that this will create the current schema + // further additional columns should be skipped. sqlite_exec_void_loglevel(loglevel, "PRAGMA auto_vacuum=2;", END); if ( sqlite_exec_void_retry(&retry, "CREATE TABLE IF NOT EXISTS MANIFESTS(" @@ -246,7 +248,8 @@ int rhizome_opendb() "name text, " "sender text collate nocase, " "recipient text collate nocase, " - "tail integer" + "tail integer, " + "manifest_hash text collate nocase" ");", END) == -1 || sqlite_exec_void_retry(&retry, "CREATE TABLE IF NOT EXISTS FILES(" @@ -274,14 +277,10 @@ int rhizome_opendb() sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "PRAGMA user_version=1;", END); } if (version<2 && meta.mtime.tv_sec != -1){ - // we need to populate these fields on upgrade from very old versions, we can simply re-insert all old manifests - // at some point we may deprecate upgrading the database and simply drop it and create a new one - // if more bundle verification is required in later upgrades, move this to the end, don't run it more than once. sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "ALTER TABLE MANIFESTS ADD COLUMN service text;", END); sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "ALTER TABLE MANIFESTS ADD COLUMN name text;", END); sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "ALTER TABLE MANIFESTS ADD COLUMN sender text collate nocase;", END); sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "ALTER TABLE MANIFESTS ADD COLUMN recipient text collate nocase;", END); - verify_bundles(); sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "PRAGMA user_version=2;", END); } if (version<3){ @@ -303,13 +302,23 @@ int rhizome_opendb() sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "DROP TABLE IF EXISTS VERIFICATIONS; ", END); sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "DROP TABLE IF EXISTS FILEMANIFESTS;", END); } - if (version<7){ - if (meta.mtime.tv_sec != -1){ - sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "ALTER TABLE FILES ADD COLUMN last_verified integer;", END); - } + if (version<7 && meta.mtime.tv_sec != -1){ + sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "ALTER TABLE FILES ADD COLUMN last_verified integer;", END); sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "PRAGMA user_version=7;", END); } + if (version<8){ + if (meta.mtime.tv_sec != -1) + sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "ALTER TABLE MANIFESTS ADD COLUMN manifest_hash text collate nocase;", END); + sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "CREATE INDEX IF NOT EXISTS IDX_MANIFEST_HASH ON MANIFESTS(manifest_hash);", END); + + // we need to populate fields on upgrade from older versions, we can simply re-insert all old manifests + // if more bundle verification is required in later upgrades, move this to the end, don't run it more than once. + verify_bundles(); + + sqlite_exec_void_loglevel(LOG_LEVEL_WARN, "PRAGMA user_version=8;", END); + } + // TODO recreate tables with collate nocase on all hex columns /* Future schema updates should be performed here. @@ -1314,9 +1323,10 @@ int rhizome_store_manifest(rhizome_manifest *m) "name," "sender," "recipient," - "tail" + "tail," + "manifest_hash" ") VALUES(" - "?,?,?,?,?,?,?,?,?,?,?,?,?" + "?,?,?,?,?,?,?,?,?,?,?,?,?,?" ");", RHIZOME_BID_T, &m->cryptoSignPublic, STATIC_BLOB, m->manifestdata, m->manifest_all_bytes, @@ -1332,6 +1342,7 @@ int rhizome_store_manifest(rhizome_manifest *m) SID_T|NUL, m->has_sender ? &m->sender : NULL, SID_T|NUL, m->has_recipient ? &m->recipient : NULL, INT64, m->tail, + RHIZOME_FILEHASH_T, &m->manifesthash, END ) ) == NULL)