make sure all required drivers succeed on put/delete; make sure we verify both compressed and uncompressed pubkey hashes when given a pubkey has to use to verify data

This commit is contained in:
Jude Nelson
2017-03-22 15:00:43 -04:00
parent 7cb38ef42e
commit 576bc21a2c

View File

@@ -246,6 +246,22 @@ def sign_data_tombstone( tombstone_data, data_privkey ):
return '{}:{}'.format(tombstone_data, sigb64)
def parse_data_tombstone( signed_tombstone ):
"""
Parse a signed data tombstone
"""
parts = signed_tombstone.rsplit(":", 1)
if len(parts) != 2:
return {'error': 'Missing signature'}
tombstone_data, sigb64 = parts[0], parts[1]
if not tombstone_data.startswith('delete:'):
return {'error': 'Missing delete: crib'}
tombstone_payload = tombstone_data[len('delete:'):]
return {'tombstone_payload': tombstone_payload, 'sigb64': sigb64}
def verify_data_tombstone( signed_tombstone, data_pubkey ):
"""
Verify the authenticity of a data tombstone
@@ -428,7 +444,10 @@ def parse_mutable_data_v2(mutable_data_json_txt, public_key_hex, public_key_hash
log.debug("Try verify with {}".format(pubkey_hash))
if keylib.public_key_to_address(pubk_hex) == pubkey_hash:
pubk_compressed = keylib.key_formatting.compress(pubk_hex)
pubk_uncompressed = keylib.key_formatting.decompress(pubk_hex)
if keylib.public_key_to_address(pubk_compressed) == pubkey_hash or keylib.public_key_to_address(pubk_uncompressed) == pubkey_hash:
if verify_data_payload( data_txt, pubk_hex, sig_b64 ):
log.debug("Verified payload with public key hash {} ({})".format(pubk_hex, pubkey_hash))
return data_txt
@@ -854,6 +873,8 @@ def put_immutable_data(data_json, txid, data_hash=None, data_text=None, required
data_hash = str(data_hash)
successes = 0
required_successes = 0
msg = 'put_immutable_data({}), required={}, skip={}'
log.debug(msg.format(data_hash, ','.join(required), ','.join(skip)))
@@ -896,8 +917,11 @@ def put_immutable_data(data_json, txid, data_hash=None, data_text=None, required
log.debug('Replication succeeded with "{}"'.format(handler.__name__))
successes += 1
if handler.__name__ in required:
required_successes += 1
# failed everywhere or succeeded somewhere
return None if successes == 0 else data_hash
return None if successes == 0 and required_successes == len(required) else data_hash
def put_mutable_data(fq_data_id, data_text_or_json, data_privkey=None, data_pubkey=None, data_signature=None, profile=False, blockchain_id=None, required=None, skip=None, required_exclusive=False):
@@ -935,6 +959,7 @@ def put_mutable_data(fq_data_id, data_text_or_json, data_privkey=None, data_pubk
serialized_data = serialize_mutable_data(data_text_or_json, data_privkey=data_privkey, data_pubkey=data_pubkey, data_signature=data_signature, profile=profile)
successes = 0
required_successes = 0
log.debug('put_mutable_data({}), required={}, skip={} required_exclusive={}'.format(fq_data_id, ','.join(required), ','.join(skip), required_exclusive))
if BLOCKSTACK_TEST:
@@ -972,8 +997,12 @@ def put_mutable_data(fq_data_id, data_text_or_json, data_privkey=None, data_pubk
return None
if rc:
log.debug("Replicated {} bytes with {}".format(len(serialized_data), handler.__name__))
log.debug("Replicated {} bytes with {} (rc = {})".format(len(serialized_data), handler.__name__, rc))
successes += 1
if handler.__name__ in required:
required_successes += 1
continue
if handler.__name__ not in required:
@@ -984,7 +1013,7 @@ def put_mutable_data(fq_data_id, data_text_or_json, data_privkey=None, data_pubk
return None
# failed everywhere or succeeded somewhere
return (successes > 0)
return (successes > 0) and (required_successes >= len(required))
def delete_immutable_data(data_hash, txid, privkey=None, signed_data_tombstone=None):
@@ -1053,6 +1082,8 @@ def delete_mutable_data(fq_data_id, privatekey=None, signed_data_tombstone=None,
ts = make_mutable_data_tombstone(fq_data_id)
signed_data_tombstone = sign_data_tombstone(ts, privatekey)
required_successes = 0
# remove data
for handler in storage_handlers:
if handler.__name__ in skip:
@@ -1076,8 +1107,11 @@ def delete_mutable_data(fq_data_id, privatekey=None, signed_data_tombstone=None,
if not rc and handler.__name__ in required:
log.error("Failed to delete from required storage driver {}".format(handler.__name__))
return False
elif handler.__name__ in required:
required_successes += 1
return True
return required_successes >= len(required)
def get_announcement(announcement_hash):