def file_key_retire( blockchain_id, file_key, config_path=CONFIG_PATH, wallet_keys=None ):
    """
    Retire the given key.  Move it to the head of the old key bundle list
    @file_key should be data returned by file_key_lookup
    Return {'status': True} on success
    Return {'error': ...} on error
    """

    config_dir = os.path.dirname(config_path)
    url = file_url_expired_keys( blockchain_id )
    proxy = blockstack_client.get_default_proxy( config_path=config_path )
        
    old_key_bundle_res = blockstack_client.data_get( url, wallet_keys=wallet_keys, proxy=proxy )
    if 'error' in old_key_bundle_res:
        log.warn('Failed to get old key bundle: %s' % old_key_bundle_res['error'])
        old_key_list = []

    else:
        old_key_list = old_key_bundle_res['data']['old_keys']
        for old_key in old_key_list:
            if old_key['key_id'] == file_key['key_id']:
                # already present 
                log.warning("Key %s is already retired" % file_key['key_id'])
                return {'status': True}

    old_key_list.insert(0, file_key )

    res = blockstack_client.data_put( url, {'old_keys': old_key_list}, wallet_keys=wallet_keys, proxy=proxy )
    if 'error' in res:
        log.error("Failed to append to expired key bundle: %s" % res['error'])
        return {'error': 'Failed to append to expired key list'}

    return {'status': True}
Ejemplo n.º 2
0
        return {'error': 'Failed to sign'}
   
    # replicate 
    app_bin = None
    with open(path, "r") as f:
        app_bin = f.read()

    data = {
        'sender_key_id': res['sender_key_id'],
        'sig': res['sig'],
        'app': base64.b64encode( app_bin )
    }

    fq_data_name = app_fq_data_name( app_name )
    proxy = blockstack_client.get_default_proxy( config_path=client_config_path )
    res = blockstack_client.data_put( blockstack_client.make_mutable_data_url( sender_blockchain_id, fq_data_name, version ), data, wallet_keys=wallet_keys, proxy=proxy )
    if 'error' in res:
        log.error("Failed to upload app '%s': %s" % (fq_data_name, res['error']))
        return {'error': 'Failed to upload data'}

    return {'status': True, 'sender_key_id': data['sender_key_id'], 'sig': data['sig']}



def app_download( sender_blockchain_id, appname, config_path=CONFIG_PATH, wallet_keys=None, version=None, appdir=None ):
    """
    Fetch the application to a temporary location on disk.
    Verify that it was signed by its creator.
    Decompress the contents.
    Return {'status': True, 'root': path, 'tag': version or hash} on success
    Return {'error': ...} on error
Ejemplo n.º 3
0
def file_put(blockchain_id,
             hostname,
             recipient_blockchain_ids,
             data_name,
             input_path,
             passphrase=None,
             config_path=CONFIG_PATH,
             wallet_keys=None):
    """
    Send a file to the given recipient, encrypted and signed with the
    given blockchain ID.
    Allow each recipient to receive the data on each of their hosts.
    Return {'status': True} on success, and upload to cloud storage
    Return {'error': ...} on error
    """
    fd, output_path = tempfile.mkstemp(prefix="blockstack-file-")
    os.fchmod(fd, 0600)
    os.close(fd)

    config_dir = os.path.dirname(config_path)
    client_config_path = os.path.join(config_dir,
                                      blockstack_client.CONFIG_FILENAME)

    all_recipients = []

    # make available to all other hosts for this blockchain_id
    my_hosts = file_list_hosts(blockchain_id,
                               wallet_keys=wallet_keys,
                               config_path=config_path)
    if 'error' in my_hosts:
        log.error("Failed to list hosts: %s" % my_hosts['error'])
        os.unlink(output_path)
        return {'error': 'Failed to look up sender keys'}

    if hostname in my_hosts:
        my_hosts.remove(hostname)

    all_recipients += [(blockchain_id, host) for host in my_hosts['hosts']]

    # make available to all hosts for each recipient
    for recipient_blockchain_id in recipient_blockchain_ids:
        their_hosts = file_list_hosts(recipient_blockchain_id,
                                      wallet_keys=wallet_keys,
                                      config_path=config_path)
        if 'error' in their_hosts:
            log.error("Failed to list hosts for %s: %s" %
                      (recipient_blockchain_id, their_hosts['error']))
            os.unlink(output_path)
            return {'error': 'Failed to look up recipient keys'}

        all_recipients += [(recipient_blockchain_id, host)
                           for host in their_hosts['hosts']]

    # encrypt
    res = file_encrypt(blockchain_id,
                       hostname,
                       all_recipients,
                       input_path,
                       output_path,
                       passphrase=passphrase,
                       config_path=config_path,
                       wallet_keys=wallet_keys)
    if 'error' in res:
        log.error("Failed to encrypt: %s" % res['error'])
        os.unlink(output_path)
        return {'error': 'Failed to encrypt'}

    # load up
    with open(output_path, "r") as f:
        ciphertext = f.read()

    message = {'ciphertext': ciphertext, 'sender_key_id': res['sender_key_id']}

    # put to mutable storage
    fq_data_name = file_fq_data_name(data_name)
    proxy = blockstack_client.get_default_proxy(config_path=client_config_path)

    res = blockstack_client.data_put(blockstack_client.make_mutable_data_url(
        blockchain_id, fq_data_name, None),
                                     message,
                                     wallet_keys=wallet_keys,
                                     proxy=proxy)
    if 'error' in res:
        log.error("Failed to put data: %s" % res['error'])
        os.unlink(output_path)
        return {'error': 'Failed to replicate data'}

    os.unlink(output_path)
    return {'status': True}
def scenario( wallets, **kw ):

    global put_result, wallet_keys, legacy_profile, zonefile_hash, zonefile_hash_2, immutable_hash


    testlib.blockstack_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey )
    testlib.next_block( **kw )

    testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey )
    testlib.next_block( **kw )

    testlib.blockstack_namespace_ready( "test", wallets[1].privkey )
    testlib.next_block( **kw )

    testlib.blockstack_name_preorder( "foo.test", wallets[2].privkey, wallets[3].addr )
    testlib.blockstack_name_preorder( "bar.test", wallets[5].privkey, wallets[6].addr )
    testlib.next_block( **kw )
    
    testlib.blockstack_name_register( "foo.test", wallets[2].privkey, wallets[3].addr )
    testlib.blockstack_name_register( "bar.test", wallets[5].privkey, wallets[6].addr )
    testlib.next_block( **kw )

    test_proxy = testlib.TestAPIProxy()
    blockstack_client.set_default_proxy( test_proxy )
    wallet_keys = blockstack_client.make_wallet_keys( owner_privkey=wallets[3].privkey, data_privkey=wallets[4].privkey, payment_privkey=wallets[8].privkey )
    wallet_keys_2 = blockstack_client.make_wallet_keys( owner_privkey=wallets[6].privkey, data_privkey=wallets[7].privkey, payment_privkey=wallets[9].privkey )

    # set up legacy profile hash
    legacy_txt = json.dumps(legacy_profile,sort_keys=True)
    legacy_hash = pybitcoin.hex_hash160( legacy_txt )

    result_1 = testlib.blockstack_name_update( "foo.test", legacy_hash, wallets[3].privkey )
    result_2 = testlib.blockstack_name_update( "bar.test", legacy_hash, wallets[6].privkey )
    testlib.next_block( **kw )

    rc = blockstack_client.storage.put_immutable_data( None, result_1['transaction_hash'], data_hash=legacy_hash, data_text=legacy_txt )
    assert rc is not None

    rc = blockstack_client.storage.put_immutable_data( None, result_2['transaction_hash'], data_hash=legacy_hash, data_text=legacy_txt )
    assert rc is not None

    testlib.next_block( **kw )

    # migrate 
    res = testlib.migrate_profile( "foo.test", proxy=test_proxy, wallet_keys=wallet_keys )
    if 'error' in res:
        res['test'] = 'Failed to initialize foo.test profile'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return 
    else:
        zonefile_hash = res['zonefile_hash']

    # migrate 
    res = testlib.migrate_profile( "bar.test", proxy=test_proxy, wallet_keys=wallet_keys_2 )
    if 'error' in res:
        res['test'] = 'Failed to initialize foo.test profile'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return 
    else:
        zonefile_hash_2 = res['zonefile_hash']

    # tell serialization-checker that value_hash can be ignored here
    print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash"
    sys.stdout.flush()
    
    testlib.next_block( **kw )

    # start up RPC for 'foo.test'
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] ) 

    # put immutable
    put_result = blockstack_client.put_immutable( "foo.test", "hello_world_immutable", {"hello": "world"}, proxy=test_proxy, wallet_keys=wallet_keys )
    if 'error' in put_result:
        print json.dumps(put_result, indent=4, sort_keys=True )
        error = True
        return

    immutable_hash = put_result['immutable_data_hash']
    testlib.expect_atlas_zonefile(put_result['zonefile_hash'])

    # tell serialization-checker that value_hash can be ignored here
    print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash"
    sys.stdout.flush()
    
    # wait for confirmation
    for i in xrange(0, 12):
        testlib.next_block( **kw )

    print "waiting for confirmation"
    time.sleep(10)

    # start up RPC for 'bar.test'
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys_2['payment_privkey'], wallet_keys_2['owner_privkey'], wallet_keys_2['data_privkey'] ) 
    put_result = blockstack_client.put_mutable( "bar.test", "hello_world_mutable", {"hello": "world"}, proxy=test_proxy, wallet_keys=wallet_keys_2 )
    if 'error' in put_result:
        print json.dumps(put_result, indent=4, sort_keys=True )
        error = True
        return
    
    testlib.next_block( **kw )

    # put mutable data with the URL 
    res = blockstack_client.data_put( "blockstack://foo.test/foo_data2", {"hello2": "world2"}, proxy=test_proxy, wallet_keys=wallet_keys )
    if 'error' in res:
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return

    # put immutable data with the URL
    # start up RPC for 'foo.test'
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] ) 
    res = blockstack_client.data_put( "blockstack://foo_immutable.foo.test", {'hello3': 'world3'}, proxy=test_proxy, wallet_keys=wallet_keys )
    if 'error' in res:
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return
    
    # tell serialization-checker that value_hash can be ignored here
    print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash"
    sys.stdout.flush()
    
    testlib.next_block( **kw )

    # app data
    data_pk = wallets[-1].privkey
    data_pub = wallets[-1].pubkey_hex

    res = blockstack_client.create_app_account("foo.test", "serviceFoo", "serviceFooID", "foo://foo.com", ["disk"], data_pub, proxy=test_proxy, wallet_keys=wallet_keys )
    if 'error' in res:
        res['test'] = 'Failed to create foo.test account'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return

    # put some data into the account
    res = blockstack_client.put_app_data( "foo.test", "serviceFoo", "serviceFooID", "foo_app_data", "foo_app_payload", data_pk, proxy=test_proxy )
    if 'error' in res:
        res['test'] = 'Failed to put app data'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return

    # put some app data, using the blockstack URL
    res = blockstack_client.data_put( "blockstack://[email protected]/foo_app_data2#3", "foo_app_payload2", data_privkey=data_pk, proxy=test_proxy )
    if 'error' in res:
        res['test'] = 'Failed to put app data'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return

    testlib.next_block( **kw )
Ejemplo n.º 5
0
def file_put( blockchain_id, hostname, recipient_blockchain_ids, data_name, input_path, passphrase=None, config_path=CONFIG_PATH, wallet_keys=None ):
    """
    Send a file to the given recipient, encrypted and signed with the
    given blockchain ID.
    Allow each recipient to receive the data on each of their hosts.
    Return {'status': True} on success, and upload to cloud storage
    Return {'error': ...} on error
    """
    fd, output_path = tempfile.mkstemp( prefix="blockstack-file-" )
    os.fchmod( fd, 0600 )
    os.close(fd)

    config_dir = os.path.dirname(config_path)
    client_config_path = os.path.join(config_dir, blockstack_client.CONFIG_FILENAME )

    all_recipients = []
    
    # make available to all other hosts for this blockchain_id
    my_hosts = file_list_hosts( blockchain_id, wallet_keys=wallet_keys, config_path=config_path )
    if 'error' in my_hosts:
        log.error("Failed to list hosts: %s" % my_hosts['error'])
        os.unlink(output_path)
        return {'error': 'Failed to look up sender keys'}

    if hostname in my_hosts:
        my_hosts.remove(hostname)

    all_recipients += [(blockchain_id, host) for host in my_hosts['hosts']]

    # make available to all hosts for each recipient 
    for recipient_blockchain_id in recipient_blockchain_ids:
        their_hosts = file_list_hosts( recipient_blockchain_id, wallet_keys=wallet_keys, config_path=config_path )
        if 'error' in their_hosts:
            log.error("Failed to list hosts for %s: %s" % (recipient_blockchain_id, their_hosts['error']))
            os.unlink(output_path)
            return {'error': 'Failed to look up recipient keys'}

        all_recipients += [(recipient_blockchain_id, host) for host in their_hosts['hosts']]

    # encrypt
    res = file_encrypt( blockchain_id, hostname, all_recipients, input_path, output_path, passphrase=passphrase, config_path=config_path, wallet_keys=wallet_keys )
    if 'error' in res:
        log.error("Failed to encrypt: %s" % res['error'])
        os.unlink(output_path)
        return {'error': 'Failed to encrypt'}

    # load up 
    with open(output_path, "r") as f:
        ciphertext = f.read()

    message = {'ciphertext': ciphertext, 'sender_key_id': res['sender_key_id']}

    # put to mutable storage 
    fq_data_name = file_fq_data_name( data_name ) 
    proxy = blockstack_client.get_default_proxy( config_path=client_config_path )

    res = blockstack_client.data_put( blockstack_client.make_mutable_data_url( blockchain_id, fq_data_name, None ), message, wallet_keys=wallet_keys, proxy=proxy )
    if 'error' in res:
        log.error("Failed to put data: %s" % res['error'])
        os.unlink(output_path)
        return {'error': 'Failed to replicate data'}

    os.unlink(output_path)
    return {'status': True}