mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2025-01-31 08:25:35 +00:00
mutable: use proper enable/renew/cancel secrets
This commit is contained in:
parent
1e8a693512
commit
59632c6812
@ -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
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user