def file_key_lookup(blockchain_id, index, hostname, key_id=None, config_path=CONFIG_PATH, wallet_keys=None): """ Get the file-encryption GPG key for the given blockchain ID, by index. if index == 0, then give back the current key if index > 0, then give back an older (revoked) key. if key_id is given, index and hostname will be ignored Return {'status': True, 'key_data': ..., 'key_id': key_id, OPTIONAL['stale_key_index': idx]} on success Return {'error': ...} on failure """ log.debug("lookup '%s' key for %s (index %s, key_id = %s)" % (hostname, blockchain_id, index, key_id)) conf = get_config(config_path) config_dir = os.path.dirname(config_path) proxy = blockstack_client.get_default_proxy(config_path=config_path) immutable = conf['immutable_key'] if key_id is not None: # we know exactly which key to get # try each current key hosts_listing = file_list_hosts(blockchain_id, wallet_keys=wallet_keys, config_path=config_path) if 'error' in hosts_listing: log.error("Failed to list hosts for %s: %s" % (blockchain_id, hosts_listing['error'])) return {'error': 'Failed to look up hosts'} hosts = hosts_listing['hosts'] for hostname in hosts: file_key = blockstack_gpg.gpg_app_get_key(blockchain_id, APP_NAME, hostname, immutable=immutable, key_id=key_id, config_dir=config_dir) if 'error' not in file_key: if key_id == file_key['key_id']: # success! return file_key # check previous keys... url = file_url_expired_keys(blockchain_id) old_key_bundle_res = blockstack_client.data_get( url, wallet_keys=wallet_keys, proxy=proxy) if 'error' in old_key_bundle_res: return old_key_bundle_res old_key_list = old_key_bundle_res['data']['old_keys'] for i in xrange(0, len(old_key_list)): old_key = old_key_list[i] if old_key['key_id'] == key_id: # success! ret = {} ret.update(old_key) ret['stale_key_index'] = i + 1 return old_key return {'error': 'No such key %s' % key_id} elif index == 0: file_key = blockstack_gpg.gpg_app_get_key(blockchain_id, APP_NAME, hostname, immutable=immutable, key_id=key_id, config_dir=config_dir) if 'error' in file_key: return file_key return file_key else: # get the bundle of revoked keys url = file_url_expired_keys(blockchain_id) old_key_bundle_res = blockstack_client.data_get( url, wallet_keys=wallet_keys, proxy=proxy) if 'error' in old_key_bundle_res: return old_key_bundle_res old_key_list = old_key_bundle_res['data']['old_keys'] if index >= len(old_key_list) + 1: return {'error': 'Index out of bounds: %s' % index} return old_key_list[index - 1]
def check( state_engine ): global wallet_keys, wallet_keys_2, key_names, error, gpghome if error: print "Key operation failed." return False # not revealed, but ready ns = state_engine.get_namespace_reveal( "test" ) if ns is not None: print "namespace not ready" return False ns = state_engine.get_namespace( "test" ) if ns is None: print "no namespace" return False if ns['namespace_id'] != 'test': print "wrong namespace" return False # not preordered names = ['foo.test', 'bar.test'] wallet_keys_list = [wallet_keys, wallet_keys_2] for i in xrange(0, len(names)): name = names[i] wallet_payer = 3 * (i+1) - 1 wallet_owner = 3 * (i+1) wallet_data_pubkey = 3 * (i+1) + 1 wallet_keys = wallet_keys_list[i] key_res = key_names[name] preorder = state_engine.get_name_preorder( name, pybitcoin.make_pay_to_address_script(wallets[wallet_payer].addr), wallets[wallet_owner].addr ) if preorder is not None: print "still have preorder" return False # registered name_rec = state_engine.get_name( name ) if name_rec is None: print "name does not exist" return False # owned if name_rec['address'] != wallets[wallet_owner].addr or name_rec['sender'] != pybitcoin.make_pay_to_address_script(wallets[wallet_owner].addr): print "name has wrong owner" return False # account listing exists, and other keys are deleted account_key_listing = blockstack_gpg.gpg_list_profile_keys( name ) secure_app_listing = blockstack_gpg.gpg_list_app_keys( name, "secure_messaging" ) less_secure_app_listing = blockstack_gpg.gpg_list_app_keys( name, "less-secure_messaging" ) if 'error' in account_key_listing: print json.dumps(account_key_listing) return False if len(account_key_listing) != 1: print "Invalid account keys:\n%s" % json.dumps(account_key_listing) return False key_id, key_url = account_key_listing[0]['identifier'], account_key_listing[0]['contentUrl'] if key_url != key_res[0]['key_url']: print "Key ID mismatch (account): %s != %s\nFull listing:\n%s\n\nKeys we generated:\n%s\n" % \ (key_url, key_res[0]['key_url'], account_key_listing[0], json.dumps(key_res, indent=4, sort_keys=True)) return False # immutable listings exist, and other keys are deleted if 'error' in secure_app_listing: print json.dumps(secure_app_listing) return False if len(secure_app_listing) != 1: print "Invalid immutable keys:\n%s" % json.dumps(secure_app_listing) return False key_id, key_url = secure_app_listing[0]['keyName'], secure_app_listing[0]['contentUrl'] if key_url != key_res[1]['key_url']: print "Key ID mismatch (immutable app): %s != %s\nFull listing:\n%s\n\nKeys we generated:\n%s\n" % \ (key_url, key_res[1]['key_url'], secure_app_listing[0], json.dumps(key_res, indent=4, sort_keys=True)) return False # mutable listings exist, and other keys are deleted if 'error' in less_secure_app_listing: print json.dumps(less_secure_app_listing) return False if len(less_secure_app_listing) != 1: print "Invalid mutable keys (mutable app):\n%s" % json.dumps(less_secure_app_listing) return False key_id, key_url = less_secure_app_listing[0]['keyName'], less_secure_app_listing[0]['contentUrl'] if key_url != key_res[2]['key_url']: print "Key ID mismatch: %s != %s\nFull listing:\n%s\n\nKeys we generated:\n%s\n" % \ (key_url, key_res[2]['key_url'], less_secure_app_listing[0], json.dumps(key_res, indent=4, sort_keys=True)) return False profile_key = blockstack_gpg.gpg_profile_get_key( name, account_key_listing[0]['keyName'], gpghome=gpghome ) if 'error' in profile_key: print "no key in account %s: %s" % (account_key_listing, profile_key['error']) return False secure_app_key = blockstack_gpg.gpg_app_get_key( name, "secure_messaging", secure_app_listing[0]['keyName'], \ immutable=True ) if 'error' in secure_app_key: print "no key in secure_messaging listing %s: %s" % (secure_app_listing, secure_app_key['error']) return False less_secure_app_key = blockstack_gpg.gpg_app_get_key( name, "less-secure_messaging", less_secure_app_listing[0]['keyName'] ) if 'error' in less_secure_app_key: print "no key in less-secure_messaging listing %s: %s" % (less_secure_app_listing, less_secure_app_key['error']) return False return True
def file_key_lookup( blockchain_id, index, hostname, key_id=None, config_path=CONFIG_PATH, wallet_keys=None ): """ Get the file-encryption GPG key for the given blockchain ID, by index. if index == 0, then give back the current key if index > 0, then give back an older (revoked) key. if key_id is given, index and hostname will be ignored Return {'status': True, 'key_data': ..., 'key_id': key_id, OPTIONAL['stale_key_index': idx]} on success Return {'error': ...} on failure """ log.debug("lookup '%s' key for %s (index %s, key_id = %s)" % (hostname, blockchain_id, index, key_id)) conf = get_config( config_path ) config_dir = os.path.dirname(config_path) proxy = blockstack_client.get_default_proxy( config_path=config_path ) immutable = conf['immutable_key'] if key_id is not None: # we know exactly which key to get # try each current key hosts_listing = file_list_hosts( blockchain_id, wallet_keys=wallet_keys, config_path=config_path ) if 'error' in hosts_listing: log.error("Failed to list hosts for %s: %s" % (blockchain_id, hosts_listing['error'])) return {'error': 'Failed to look up hosts'} hosts = hosts_listing['hosts'] for hostname in hosts: file_key = blockstack_gpg.gpg_app_get_key( blockchain_id, APP_NAME, hostname, immutable=immutable, key_id=key_id, config_dir=config_dir ) if 'error' not in file_key: if key_id == file_key['key_id']: # success! return file_key # check previous keys... url = file_url_expired_keys( blockchain_id ) old_key_bundle_res = blockstack_client.data_get( url, wallet_keys=wallet_keys, proxy=proxy ) if 'error' in old_key_bundle_res: return old_key_bundle_res old_key_list = old_key_bundle_res['data']['old_keys'] for i in xrange(0, len(old_key_list)): old_key = old_key_list[i] if old_key['key_id'] == key_id: # success! ret = {} ret.update( old_key ) ret['stale_key_index'] = i+1 return old_key return {'error': 'No such key %s' % key_id} elif index == 0: file_key = blockstack_gpg.gpg_app_get_key( blockchain_id, APP_NAME, hostname, immutable=immutable, key_id=key_id, config_dir=config_dir ) if 'error' in file_key: return file_key return file_key else: # get the bundle of revoked keys url = file_url_expired_keys( blockchain_id ) old_key_bundle_res = blockstack_client.data_get( url, wallet_keys=wallet_keys, proxy=proxy ) if 'error' in old_key_bundle_res: return old_key_bundle_res old_key_list = old_key_bundle_res['data']['old_keys'] if index >= len(old_key_list)+1: return {'error': 'Index out of bounds: %s' % index} return old_key_list[index-1]