mutable: use proper enable/renew/cancel secrets

This commit is contained in:
Brian Warner 2007-11-05 21:51:08 -07:00
parent 1e8a693512
commit 59632c6812
4 changed files with 42 additions and 14 deletions

View File

@ -73,7 +73,7 @@ class NewDirectoryNode:
def _encrypt_rwcap(self, rwcap): def _encrypt_rwcap(self, rwcap):
assert isinstance(rwcap, str) assert isinstance(rwcap, str)
IV = os.urandom(16) 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 counterstart = "\x00"*16
cryptor = AES.new(key=key, mode=AES.MODE_CTR, counterstart=counterstart) cryptor = AES.new(key=key, mode=AES.MODE_CTR, counterstart=counterstart)
crypttext = cryptor.encrypt(rwcap) crypttext = cryptor.encrypt(rwcap)
@ -85,7 +85,7 @@ class NewDirectoryNode:
IV = encwrcap[:16] IV = encwrcap[:16]
crypttext = encwrcap[16:-32] crypttext = encwrcap[16:-32]
mac = encwrcap[-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): if mac != hashutil.hmac(key, IV+crypttext):
raise IntegrityCheckError("HMAC does not match, crypttext is corrupted") raise IntegrityCheckError("HMAC does not match, crypttext is corrupted")
counterstart = "\x00"*16 counterstart = "\x00"*16

View File

@ -41,6 +41,9 @@ class MutableFileNode:
# wants to get our contents, we'll pull from shares and fill those # wants to get our contents, we'll pull from shares and fill those
# in. # in.
self._uri = IMutableFileURI(myuri) self._uri = IMutableFileURI(myuri)
self._writekey = self._uri.writekey
self._readkey = self._uri.readkey
self._storage_index = self._uri.storage_index
return self return self
def create(self, initial_contents): def create(self, initial_contents):
@ -58,6 +61,19 @@ class MutableFileNode:
return d 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): def get_uri(self):
return self._uri.to_string() return self._uri.to_string()
@ -482,8 +498,15 @@ class Publish(ShareFormattingMixin):
dl = [] dl = []
# ok, send the messages! # ok, send the messages!
self._surprised = False self._surprised = False
for peerid, tw_vectors in peer_messages.items(): 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) tw_vectors, read_vector)
d.addCallback(self._got_write_answer, d.addCallback(self._got_write_answer,
peerid, expected_old_shares[peerid]) peerid, expected_old_shares[peerid])
@ -493,18 +516,14 @@ class Publish(ShareFormattingMixin):
d.addCallback(lambda res: self._surprised) d.addCallback(lambda res: self._surprised)
return d return d
def _do_testreadwrite(self, peerid, peer_storage_servers, def _do_testreadwrite(self, peerid, peer_storage_servers, secrets,
tw_vectors, read_vector): tw_vectors, read_vector):
conn = peer_storage_servers[peerid] conn = peer_storage_servers[peerid]
storage_index = self._node._uri.storage_index 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", d = conn.callRemote("slot_testv_and_readv_and_writev",
storage_index, storage_index,
(write_enabler, renew_secret, cancel_secret), secrets,
tw_vectors, tw_vectors,
read_vector) read_vector)
return d return d

View File

@ -46,10 +46,6 @@ class FakeFilenode(mutable.MutableFileNode):
counter = itertools.count(1) counter = itertools.count(1)
all_contents = {} all_contents = {}
def init_from_uri(self, myuri):
self._uri = myuri
self.writekey = myuri.writekey
return self
def create(self, initial_contents): def create(self, initial_contents):
count = self.counter.next() count = self.counter.next()
self.init_from_uri(uri.WriteableSSKFileURI("key%d" % count, self.init_from_uri(uri.WriteableSSKFileURI("key%d" % count,
@ -72,7 +68,8 @@ class FakePublish(mutable.Publish):
shares = self._peers[peerid] shares = self._peers[peerid]
return defer.succeed(shares) 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. # always-pass: parrot the test vectors back to them.
readv = {} readv = {}
for shnum, (testv, datav, new_length) in tw_vectors.items(): for shnum, (testv, datav, new_length) in tw_vectors.items():
@ -94,6 +91,11 @@ class MyClient:
self._peerids = [tagged_hash("peerid", "%d" % i) self._peerids = [tagged_hash("peerid", "%d" % i)
for i in range(self._num_peers)] 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): def create_empty_dirnode(self):
n = FakeNewDirectoryNode(self) n = FakeNewDirectoryNode(self)
d = n.create() d = n.create()

View File

@ -120,6 +120,13 @@ def mutable_rwcap_key_hash(iv, writekey):
return tagged_pair_hash("allmydata_mutable_rwcap_key_v1", iv, writekey) return tagged_pair_hash("allmydata_mutable_rwcap_key_v1", iv, writekey)
def ssk_writekey_hash(privkey): def ssk_writekey_hash(privkey):
return tagged_hash("allmydata_mutable_writekey_v1", 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): def ssk_pubkey_fingerprint_hash(pubkey):
return tagged_hash("allmydata_mutable_pubkey_v1", pubkey) return tagged_hash("allmydata_mutable_pubkey_v1", pubkey)