]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/commitdiff
mutable: use proper enable/renew/cancel secrets
authorBrian Warner <warner@allmydata.com>
Tue, 6 Nov 2007 04:51:08 +0000 (21:51 -0700)
committerBrian Warner <warner@allmydata.com>
Tue, 6 Nov 2007 04:51:08 +0000 (21:51 -0700)
src/allmydata/dirnode2.py
src/allmydata/mutable.py
src/allmydata/test/test_mutable.py
src/allmydata/util/hashutil.py

index 21eeeddc498ee4b82bfdf87f35f745b53d3f9b4d..5cdec39434630a55bac9bafa8a15ca2ef826597b 100644 (file)
@@ -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
index a77e3e98cf1525006d963dcfe7eaac7e0fe2f9bf..4c62dc03a758fd9a3ae5bcd616873b3c0eee5bab 100644 (file)
@@ -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
index 9acc1e6887f5caec32e5855374d088bcd08564f3..56f4285e711739b2ea1cfd7172648c82270ce546 100644 (file)
@@ -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()
index bf2747a1f6e804424c41ce9578dcbc655b087119..8424d755a79cc6d1917bd7dbebd5cd95af546e98 100644 (file)
@@ -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)