Example #1
0
    def test_signed_key(self):
        try:
            bpio.rmdir_recursive('/tmp/.bitdust_test_signed_key')
        except Exception:
            pass
        lg.set_debug_level(30)
        settings.init(base_dir='/tmp/.bitdust_test_signed_key')
        self.my_current_key = None
        try:
            os.makedirs('/tmp/.bitdust_test_signed_key/metadata/')
        except:
            pass
        fout = open('/tmp/_some_priv_key', 'w')
        fout.write(_some_priv_key)
        fout.close()
        fout = open(settings.LocalIdentityFilename(), 'w')
        fout.write(_some_identity_xml)
        fout.close()
        self.assertTrue(key.LoadMyKey(keyfilename='/tmp/_some_priv_key'))
        self.assertTrue(my_id.loadLocalIdentity())

        key_id = '[email protected]_8084'
        my_keys.erase_key(key_id, keys_folder='/tmp/')
        my_keys.register_key(key_id, _sample_private_key, keys_folder='/tmp/')
        is_valid = my_keys.validate_key(my_keys.key_obj(key_id))
        self.assertTrue(is_valid)
        my_keys.sign_key(key_id)
        signed_key_info = my_keys.get_key_info(key_id,
                                               include_private=True,
                                               include_signature=True)
        self.assertTrue(my_keys.verify_key_info_signature(signed_key_info))

        key.ForgetMyKey()
        my_id.forgetLocalIdentity()
        settings.shutdown()
        os.remove('/tmp/_some_priv_key')
        bpio.rmdir_recursive('/tmp/.bitdust_test_signed_key')
Example #2
0
def on_key_received(newpacket, info, status, error_message):
    """
    Callback will be executed when I receive a new key from one remote user.
    """
    block = encrypted.Unserialize(newpacket.Payload)
    if block is None:
        lg.err('failed reading key info from %s' % newpacket.RemoteID)
        return False
    try:
        key_data = block.Data()
        key_json = serialization.BytesToDict(key_data, keys_to_text=True, values_to_text=True)
        key_id = key_json['key_id']
        key_label = key_json.get('label', '')
        key_id, key_object = my_keys.read_key_info(key_json)
        if key_object.isSigned():
            if not my_keys.verify_key_info_signature(key_json):
                raise Exception('key signature verification failed')
        if key_object.isPublic():
            # received key is a public key
            if my_keys.is_key_registered(key_id):
                # but we already have a key with that ID
                if my_keys.is_key_private(key_id):
                    # we should not overwrite existing private key
                    raise Exception('private key already registered')
                if my_keys.get_public_key_raw(key_id) != key_object.toPublicString():
                    # and we should not overwrite existing public key as well
                    raise Exception('another public key already registered with that ID and it is not matching')
                p2p_service.SendAck(newpacket)
                lg.warn('received existing public key: %s, skip' % key_id)
                return True
            if not my_keys.register_key(key_id, key_object, label=key_label):
                raise Exception('key register failed')
            else:
                lg.info('added new key %s, is_public=%s' % (key_id, key_object.isPublic()))
            p2p_service.SendAck(newpacket)
            if _Debug:
                lg.info('received and stored locally a new key %s, include_private=%s' % (key_id, key_json.get('include_private')))
            return True
        # received key is a private key
        if my_keys.is_key_registered(key_id):
            # check if we already have that key
            if my_keys.is_key_private(key_id):
                # we have already private key with same ID!!!
                if my_keys.get_private_key_raw(key_id) != key_object.toPrivateString():
                    # and this is a new private key : we should not overwrite!
                    raise Exception('private key already registered and it is not matching')
                # this is the same private key
                p2p_service.SendAck(newpacket)
                lg.warn('received existing private key: %s, skip' % key_id)
                return True
            # but we have a public key with same ID already
            if my_keys.get_public_key_raw(key_id) != key_object.toPublicString():
                # and we should not overwrite existing public key as well
                raise Exception('another public key already registered with that ID and it is not matching with private key')
            lg.info('erasing public key %s' % key_id)
            my_keys.erase_key(key_id)
            if not my_keys.register_key(key_id, key_object, label=key_label):
                raise Exception('key register failed')
            lg.info('added new key %s, is_public=%s' % (key_id, key_object.isPublic()))
            p2p_service.SendAck(newpacket)
            return True
        # no private key with given ID was registered
        if not my_keys.register_key(key_id, key_object, label=key_label):
            raise Exception('key register failed')
        lg.info('added new key %s, is_public=%s' % (key_id, key_object.isPublic()))
        p2p_service.SendAck(newpacket)
        return True
    except Exception as exc:
        lg.exc()
        p2p_service.SendFail(newpacket, strng.to_text(exc))
    return False
Example #3
0
def on_key_received(newpacket, info, status, error_message):
    """
    Callback will be executed when I receive a new key from one remote user.
    """
    block = encrypted.Unserialize(newpacket.Payload)
    if block is None:
        lg.err('failed reading key info from %s' % newpacket.RemoteID)
        return False
    try:
        key_data = block.Data()
        key_json = serialization.BytesToDict(key_data, keys_to_text=True, values_to_text=True)
        # key_id = strng.to_text(key_json['key_id'])
        key_label = strng.to_text(key_json.get('label', ''))
        key_id, key_object = my_keys.read_key_info(key_json)
        if key_object.isSigned():
            if not my_keys.verify_key_info_signature(key_json):
                raise Exception('received key signature verification failed: %r' % key_json)
            # TODO: must also compare "signature_pubkey" with pub key of the creator of the key!
        if key_object.isPublic():
            # received key is a public key
            if my_keys.is_key_registered(key_id):
                # but we already have a key with that ID
                if my_keys.is_key_private(key_id):
                    # we should not overwrite existing private key
                    # TODO: check other scenarios
                    raise Exception('private key already registered with %r' % key_id)
                if my_keys.get_public_key_raw(key_id) != key_object.toPublicString():
                    my_keys.erase_key(key_id)
                    if not my_keys.register_key(key_id, key_object, label=key_label):
                        raise Exception('key register failed')
                    else:
                        lg.info('replaced existing key %s, is_public=%s' % (key_id, key_object.isPublic()))
                    # normally should not overwrite existing public key
                    # TODO: look more if need to add some extra checks
                    # for example need to be able to overwrite or erase remotely some keys to cleanup
                    # raise Exception('another public key already registered with %r and new key is not matching' % key_id)
                p2p_service.SendAck(newpacket)
                lg.warn('received existing public key: %s, skip' % key_id)
                return True
            if not my_keys.register_key(key_id, key_object, label=key_label):
                raise Exception('key register failed')
            else:
                lg.info('added new key %s, is_public=%s' % (key_id, key_object.isPublic()))
            p2p_service.SendAck(newpacket)
            if _Debug:
                lg.info('received and stored locally a new key %s, include_private=%s' % (key_id, key_json.get('include_private')))
            return True
        # received key is a private key
        if my_keys.is_key_registered(key_id):
            # check if we already have that key
            if my_keys.is_key_private(key_id):
                # we have already private key with same ID!!!
                if my_keys.get_private_key_raw(key_id) != key_object.toPrivateString():
                    # and this is a new private key : we should not overwrite!
                    raise Exception('private key already registered and it is not matching with received copy')
                # this is the same private key
                p2p_service.SendAck(newpacket)
                lg.warn('received again an exact copy of already existing private key: %s, skip' % key_id)
                return True
            # but we have a public key with same ID already
            # if my_keys.get_public_key_raw(key_id) != key_object.toPublicString():
            #     # and we should not overwrite existing public key as well
            #     raise Exception('another public key already registered with that ID and it is not matching with private key')
            lg.info('erasing public key %s' % key_id)
            my_keys.erase_key(key_id)
            if not my_keys.register_key(key_id, key_object, label=key_label):
                raise Exception('key register failed')
            lg.info('added new key %s, is_public=%s' % (key_id, key_object.isPublic()))
            p2p_service.SendAck(newpacket)
            return True
        # no private key with given ID was registered
        if not my_keys.register_key(key_id, key_object, label=key_label):
            raise Exception('key register failed')
        lg.info('added new key %s, is_public=%s' % (key_id, key_object.isPublic()))
        p2p_service.SendAck(newpacket)
        return True
    except Exception as exc:
        lg.exc()
        p2p_service.SendFail(newpacket, strng.to_text(exc))
    return False
Example #4
0
def transfer_key(key_id, trusted_idurl, include_private=False, include_signature=False, timeout=10, result=None):
    """
    Actually sending given key to remote user.
    """
    if _Debug:
        lg.out(_DebugLevel, 'key_ring.transfer_key  %s -> %s' % (key_id, trusted_idurl))
    key_id = my_keys.latest_key_id(key_id)
    if not result:
        result = Deferred()
    recipient_id_obj = identitycache.FromCache(trusted_idurl)
    if not recipient_id_obj:
        lg.warn('not found "%s" in identity cache' % trusted_idurl)
        result.errback(Exception('not found "%s" in identity cache' % trusted_idurl))
        return result
    key_alias, creator_idurl = my_keys.split_key_id(key_id)
    if not key_alias or not creator_idurl:
        lg.warn('wrong key_id')
        result.errback(Exception('wrong key_id'))
        return result
    if not my_keys.is_key_registered(key_id):
        lg.warn('unknown key: "%s"' % key_id)
        result.errback(Exception('unknown key: "%s"' % key_id))
        return result
    key_object = my_keys.key_obj(key_id)
    try:
        key_json = my_keys.make_key_info(
            key_object,
            key_id=key_id,
            include_private=include_private,
            generate_signature=include_signature,
        )
    except Exception as exc:
        lg.exc()
        result.errback(exc)
        return result
    if include_signature and not my_keys.verify_key_info_signature(key_json):
        lg.err('signature verification failed after making key info: %r' % key_json)
        result.errback(Exception('signature verification failed after making key info: "%s"' % key_id))
        return result
    if _Debug:
        lg.args(_DebugLevel, key_json=key_json)
    key_data = serialization.DictToBytes(key_json, values_to_text=True)
    block = encrypted.Block(
        BackupID=key_id,
        Data=key_data,
        SessionKey=key.NewSessionKey(session_key_type=key.SessionKeyType()),
        SessionKeyType=key.SessionKeyType(),
        # encrypt data using public key of recipient
        EncryptKey=lambda inp: recipient_id_obj.encrypt(inp),
    )
    encrypted_key_data = block.Serialize()
    p2p_service.SendKey(
        remote_idurl=recipient_id_obj.getIDURL(),
        encrypted_key_data=encrypted_key_data,
        packet_id=key_id,
        callbacks={
            commands.Ack(): lambda response, info: _on_transfer_key_response(response, info, key_id, result),
            commands.Fail(): lambda response, info: _on_transfer_key_response(response, info, key_id, result),
            None: lambda pkt_out: _on_transfer_key_response(None, None, key_id, result),
        },
        timeout=timeout,
    )
    return result