From: Brian Warner Date: Tue, 6 Nov 2007 04:51:08 +0000 (-0700) Subject: mutable: use proper enable/renew/cancel secrets X-Git-Tag: allmydata-tahoe-0.7.0~283 X-Git-Url: https://git.rkrishnan.org/specifications/index.php?a=commitdiff_plain;h=59632c68128c0f4b72c7d805f7b3cf192e7926b5;p=tahoe-lafs%2Ftahoe-lafs.git mutable: use proper enable/renew/cancel secrets --- diff --git a/src/allmydata/dirnode2.py b/src/allmydata/dirnode2.py index 21eeeddc..5cdec394 100644 --- a/src/allmydata/dirnode2.py +++ b/src/allmydata/dirnode2.py @@ -73,7 +73,7 @@ class NewDirectoryNode: def _encrypt_rwcap(self, rwcap): assert isinstance(rwcap, str) IV = os.urandom(16) - key = hashutil.mutable_rwcap_key_hash(IV, self._node.writekey) + key = hashutil.mutable_rwcap_key_hash(IV, self._node.get_writekey()) counterstart = "\x00"*16 cryptor = AES.new(key=key, mode=AES.MODE_CTR, counterstart=counterstart) crypttext = cryptor.encrypt(rwcap) @@ -85,7 +85,7 @@ class NewDirectoryNode: IV = encwrcap[:16] crypttext = encwrcap[16:-32] mac = encwrcap[-32:] - key = hashutil.mutable_rwcap_key_hash(IV, self._node.writekey) + key = hashutil.mutable_rwcap_key_hash(IV, self._node.get_writekey()) if mac != hashutil.hmac(key, IV+crypttext): raise IntegrityCheckError("HMAC does not match, crypttext is corrupted") counterstart = "\x00"*16 diff --git a/src/allmydata/mutable.py b/src/allmydata/mutable.py index a77e3e98..4c62dc03 100644 --- a/src/allmydata/mutable.py +++ b/src/allmydata/mutable.py @@ -41,6 +41,9 @@ class MutableFileNode: # wants to get our contents, we'll pull from shares and fill those # in. self._uri = IMutableFileURI(myuri) + self._writekey = self._uri.writekey + self._readkey = self._uri.readkey + self._storage_index = self._uri.storage_index return self def create(self, initial_contents): @@ -58,6 +61,19 @@ class MutableFileNode: return d + def get_write_enabler(self, nodeid): + return hashutil.ssk_write_enabler_hash(self._writekey, nodeid) + def get_renewal_secret(self, nodeid): + crs = self._client.get_renewal_secret() + frs = hashutil.file_renewal_secret_hash(crs, self._storage_index) + return hashutil.bucket_renewal_secret_hash(frs, nodeid) + def get_cancel_secret(self, nodeid): + ccs = self._client.get_cancel_secret() + fcs = hashutil.file_cancel_secret_hash(ccs, self._storage_index) + return hashutil.bucket_cancel_secret_hash(fcs, nodeid) + def get_writekey(self): + return self._writekey + def get_uri(self): return self._uri.to_string() @@ -482,8 +498,15 @@ class Publish(ShareFormattingMixin): dl = [] # ok, send the messages! self._surprised = False + for peerid, tw_vectors in peer_messages.items(): - d = self._do_testreadwrite(peerid, peer_storage_servers, + + write_enabler = self._node.get_write_enabler(peerid) + renew_secret = self._node.get_renewal_secret(peerid) + cancel_secret = self._node.get_cancel_secret(peerid) + secrets = (write_enabler, renew_secret, cancel_secret) + + d = self._do_testreadwrite(peerid, peer_storage_servers, secrets, tw_vectors, read_vector) d.addCallback(self._got_write_answer, peerid, expected_old_shares[peerid]) @@ -493,18 +516,14 @@ class Publish(ShareFormattingMixin): d.addCallback(lambda res: self._surprised) return d - def _do_testreadwrite(self, peerid, peer_storage_servers, + def _do_testreadwrite(self, peerid, peer_storage_servers, secrets, tw_vectors, read_vector): conn = peer_storage_servers[peerid] storage_index = self._node._uri.storage_index - # TOTALLY BOGUS renew/cancel secrets - write_enabler = hashutil.tagged_hash("WEFOO", storage_index) - renew_secret = hashutil.tagged_hash("renewFOO", storage_index) - cancel_secret = hashutil.tagged_hash("cancelFOO", storage_index) d = conn.callRemote("slot_testv_and_readv_and_writev", storage_index, - (write_enabler, renew_secret, cancel_secret), + secrets, tw_vectors, read_vector) return d diff --git a/src/allmydata/test/test_mutable.py b/src/allmydata/test/test_mutable.py index 9acc1e68..56f4285e 100644 --- a/src/allmydata/test/test_mutable.py +++ b/src/allmydata/test/test_mutable.py @@ -46,10 +46,6 @@ class FakeFilenode(mutable.MutableFileNode): counter = itertools.count(1) all_contents = {} - def init_from_uri(self, myuri): - self._uri = myuri - self.writekey = myuri.writekey - return self def create(self, initial_contents): count = self.counter.next() self.init_from_uri(uri.WriteableSSKFileURI("key%d" % count, @@ -72,7 +68,8 @@ class FakePublish(mutable.Publish): shares = self._peers[peerid] return defer.succeed(shares) - def _do_testreadwrite(self, conn, peerid, tw_vectors, read_vector): + def _do_testreadwrite(self, peerid, peer_storage_servers, secrets, + tw_vectors, read_vector): # always-pass: parrot the test vectors back to them. readv = {} for shnum, (testv, datav, new_length) in tw_vectors.items(): @@ -94,6 +91,11 @@ class MyClient: self._peerids = [tagged_hash("peerid", "%d" % i) for i in range(self._num_peers)] + def get_renewal_secret(self): + return "I hereby permit you to renew my files" + def get_cancel_secret(self): + return "I hereby permit you to cancel my leases" + def create_empty_dirnode(self): n = FakeNewDirectoryNode(self) d = n.create() diff --git a/src/allmydata/util/hashutil.py b/src/allmydata/util/hashutil.py index bf2747a1..8424d755 100644 --- a/src/allmydata/util/hashutil.py +++ b/src/allmydata/util/hashutil.py @@ -120,6 +120,13 @@ def mutable_rwcap_key_hash(iv, writekey): return tagged_pair_hash("allmydata_mutable_rwcap_key_v1", iv, writekey) def ssk_writekey_hash(privkey): return tagged_hash("allmydata_mutable_writekey_v1", privkey) +def ssk_write_enabler_master_hash(writekey): + return tagged_hash("allmydata_mutable_write_enabler_master_v1", writekey) +def ssk_write_enabler_hash(writekey, nodeid): + assert len(nodeid) == 32 # binary! + wem = ssk_write_enabler_master_hash(writekey) + return tagged_pair_hash("allmydata_mutable_write_enabler_v1", wem, nodeid) + def ssk_pubkey_fingerprint_hash(pubkey): return tagged_hash("allmydata_mutable_pubkey_v1", pubkey)