Exemplo n.º 1
0
    def test_deterministic(self):
        password = os.urandom(32)
        gen = crypto.generate_deterministic(password)
        self.assertTrue(stringvalidators.validate_pub_key(gen[0]))
        try:
            crypto.generate_deterministic('weakpassword')
        except onionrexceptions.PasswordStrengthError:
            pass
        else:
            self.assertFalse(True)
        try:
            crypto.generate_deterministic(None)
        except TypeError:
            pass
        else:
            self.assertFalse(True)

        gen = crypto.generate_deterministic('weakpassword', bypassCheck=True)

        password = base64.b64encode(os.urandom(32))
        gen1 = crypto.generate_deterministic(password)
        gen2 = crypto.generate_deterministic(password)
        self.assertFalse(gen == gen1)
        self.assertTrue(gen1 == gen2)
        self.assertTrue(stringvalidators.validate_pub_key(gen1[0]))
Exemplo n.º 2
0
def add_peer(peerID, name=''):
    """Add a public key to the key database (misleading function name)."""
    if peerID in listkeys.list_peers() or peerID == onionrcrypto.pub_key:
        raise ValueError("specified id is already known")

    # This function simply adds a peer to the DB
    if not stringvalidators.validate_pub_key(peerID):
        return False

    conn = sqlite3.connect(dbfiles.user_id_info_db,
                           timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
    hashID = ""
    c = conn.cursor()
    t = (peerID, name, 'unknown', hashID, 0)

    for i in c.execute("SELECT * FROM peers WHERE id = ?;", (peerID, )):
        try:
            if i[0] == peerID:
                conn.close()
                return False
        except ValueError:
            pass
        except IndexError:
            pass
    c.execute(
        'INSERT INTO peers (id, name, dateSeen, hashID, trust) VALUES(?, ?, ?, ?, ?);',
        t)
    conn.commit()
    conn.close()

    return True
Exemplo n.º 3
0
    def addForwardKey(self, newKey, expire=DEFAULT_KEY_EXPIRE):
        newKey = bytesconverter.bytes_to_str(
            unpaddedbase32.repad(bytesconverter.str_to_bytes(newKey)))
        if not stringvalidators.validate_pub_key(newKey):
            # Do not add if something went wrong with the key
            raise onionrexceptions.InvalidPubkey(newKey)

        conn = sqlite3.connect(dbfiles.user_id_info_db,
                               timeout=DATABASE_LOCK_TIMEOUT)
        c = conn.cursor()

        # Get the time we're inserting the key at
        timeInsert = epoch.get_epoch()

        # Look at our current keys for duplicate key data or time
        for entry in self._getForwardKeys():
            if entry[0] == newKey:
                return False
            if entry[1] == timeInsert:
                timeInsert += 1
                # Sleep if our time is the same to prevent dupe time records
                time.sleep(1)

        # Add a forward secrecy key for the peer
        # Prepare the insert
        command = (self.publicKey, newKey, timeInsert, timeInsert + expire)

        c.execute("INSERT INTO forwardKeys VALUES(?, ?, ?, ?);", command)

        conn.commit()
        conn.close()
        return True
Exemplo n.º 4
0
def site_file(name: str, file: str)->Response:
    """Accept a site 'name', if pubkey then show multi-page site, if hash show single page site"""
    resp: str = 'Not Found'
    mime_type = mimetypes.MimeTypes().guess_type(file)[0]

    # If necessary convert the name to base32 from mnemonic
    if mnemonickeys.DELIMITER in name:
        name = mnemonickeys.get_base32(name)

    # Now make sure the key is regardless a valid base32 format ed25519 key (readding padding if necessary)
    if stringvalidators.validate_pub_key(name):
        name = unpaddedbase32.repad(name)
        resp = sitefiles.get_file(name, file)

    elif stringvalidators.validate_hash(name):
        try:
            resp = onionrblockapi.Block(name).bcontent
        except onionrexceptions.NoDataAvailable:
            abort(404)
        except TypeError:
            pass
        try:
            resp = base64.b64decode(resp)
        except binascii.Error:
            pass
    if resp == 'Not Found' or not resp:
        abort(404)
    return Response(resp, mimetype=mime_type)
Exemplo n.º 5
0
    def get_block_data(self, bHash, decrypt=False, raw=False, headerOnly=False):
        if not stringvalidators.validate_hash(bHash):
            raise onionrexceptions.InvalidHexHash(
                "block hash not valid hash format")
        bl = onionrblockapi.Block(bHash)
        if decrypt:
            bl.decrypt()
            if bl.isEncrypted and not bl.decrypted:
                raise ValueError

        if not raw:
            if not headerOnly:
                retData = {'meta':bl.bheader, 'metadata': bl.bmetadata, 'content': bl.bcontent}
                for x in list(retData.keys()):
                    try:
                        retData[x] = retData[x].decode()
                    except AttributeError:
                        pass
            else:
                validSig = False
                signer = bytesconverter.bytes_to_str(bl.signer)
                if bl.isSigned() and stringvalidators.validate_pub_key(signer) and bl.isSigner(signer):
                    validSig = True
                bl.bheader['validSig'] = validSig
                bl.bheader['meta'] = ''
                retData = {'meta': bl.bheader, 'metadata': bl.bmetadata}
            return json.dumps(retData)
        else:
            return bl.raw
Exemplo n.º 6
0
    def test_pubkey_validator(self):
        # Test ed25519 public key validity
        valids = [
            'JZ5VE72GUS3C7BOHDRIYZX4B5U5EJMCMLKHLYCVBQQF3UKHYIRRQ====',
            'JZ5VE72GUS3C7BOHDRIYZX4B5U5EJMCMLKHLYCVBQQF3UKHYIRRQ'
        ]
        invalid = [
            None, '', '    ', 'dfsg', '\n',
            'JZ5VE72GUS3C7BOHDRIYZX4B5U5EJMCMLKHLYCVBQQF3UKHYIR$Q===='
        ]

        for valid in valids:
            print('testing', valid)
            self.assertTrue(stringvalidators.validate_pub_key(valid))

        for x in invalid:
            #print('testing', x)
            self.assertFalse(stringvalidators.validate_pub_key(x))
Exemplo n.º 7
0
def _processForwardKey(api, myBlock):
    '''
        Get the forward secrecy key specified by the user for us to use
    '''
    peer = onionrusers.OnionrUser(myBlock.signer)
    key = myBlock.getMetadata('newFSKey')

    # We don't need to validate here probably, but it helps
    if stringvalidators.validate_pub_key(key):
        peer.addForwardKey(key)
    else:
        raise onionrexceptions.InvalidPubkey("%s is not a valid pubkey key" %
                                             (key, ))
Exemplo n.º 8
0
 def forwardEncrypt(self, data):
     deleteTheirExpiredKeys(self.publicKey)
     deleteExpiredKeys()
     retData = ''
     forwardKey = self._getLatestForwardKey()
     if stringvalidators.validate_pub_key(forwardKey[0]):
         retData = onionrcrypto.encryption.pub_key_encrypt(data,
                                                           forwardKey[0],
                                                           encodedData=True)
     else:
         raise onionrexceptions.InvalidPubkey(
             "No valid forward secrecy key available for this user")
     return (retData, forwardKey[0], forwardKey[1])
Exemplo n.º 9
0
    def encrypt(self):
        # peer, data
        plaintext = ""
        encrypted = ""
        # detect if signing is enabled
        sign = True
        try:
            if sys.argv[3].lower() == 'false':
                sign = False
        except IndexError:
            pass

        try:
            if not stringvalidators.validate_pub_key(sys.argv[2]):
                raise onionrexceptions.InvalidPubkey
        except (ValueError, IndexError) as e:
            logger.error("Peer public key not specified", terminal=True)
        except onionrexceptions.InvalidPubkey:
            logger.error("Invalid public key", terminal=True)
        else:
            pubkey = sys.argv[2]
            # Encrypt if public key is valid
            logger.info("Please enter your message (ctrl-d or -q to stop):",
                        terminal=True)
            try:
                for line in sys.stdin:
                    if line == '-q\n':
                        break
                    plaintext += line
            except KeyboardInterrupt:
                sys.exit(1)
            # Build Message to encrypt
            data = {}
            myPub = keypair[0]
            if sign:
                data['sig'] = signing.ed_sign(plaintext,
                                              key=keypair[1],
                                              encodeResult=True)
                data['sig'] = bytesconverter.bytes_to_str(data['sig'])
                data['signer'] = myPub
            data['data'] = plaintext
            data = json.dumps(data)
            plaintext = data
            encrypted = encryption.pub_key_encrypt(plaintext,
                                                   pubkey,
                                                   encodedData=True)
            encrypted = bytesconverter.bytes_to_str(encrypted)
            logger.info(
                'Encrypted Message: \n\nONIONR ENCRYPTED DATA %s END ENCRYPTED DATA'
                % (encrypted, ),
                terminal=True)
Exemplo n.º 10
0
def remove_user(pubkey: str) -> bool:
    '''
        Remove a user from the user database
    '''
    pubkey = mnemonickeys.get_base32(pubkey)
    if stringvalidators.validate_pub_key(pubkey):
        conn = sqlite3.connect(dbfiles.user_id_info_db,
                               timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
        c = conn.cursor()
        t = (pubkey, )
        c.execute('Delete from peers where id=?;', t)
        conn.commit()
        conn.close()

        return True
    else:
        return False
Exemplo n.º 11
0
def find_site(user_id: str) -> Union[BlockHash, None]:
    """Returns block hash str for latest block for a site by a given user id"""
    # If mnemonic delim in key, convert to base32 version
    if mnemonickeys.DELIMITER in user_id:
        user_id = mnemonickeys.get_base32(user_id)

    if not stringvalidators.validate_pub_key(user_id):
        raise onionrexceptions.InvalidPubkey

    found_site = None
    sites = blockmetadb.get_blocks_by_type('zsite')

    # Find site by searching all site blocks. eww O(N) ☹️, TODO: event based
    for site in sites:
        site = Block(site)
        if site.isSigner(user_id) and site.verifySig():
            found_site = site.hash
    return found_site
Exemplo n.º 12
0
def change_ID():
    key_manager = keymanager.KeyManager()
    try:
        key = sys.argv[2]
        key = unpaddedbase32.repad(key.encode()).decode()
    except IndexError:
        logger.warn('Specify pubkey to use', terminal=True)
    else:
        if stringvalidators.validate_pub_key(key):
            key_list = key_manager.getPubkeyList()
            if key in key_list or key.replace('=', '') in key_list:
                config.set('general.public_key', key)
                config.save()
                logger.info('Set active key to: %s' % (key, ), terminal=True)
                logger.info('Restart Onionr if it is running.', terminal=True)
            else:
                logger.warn('That key does not exist', terminal=True)
        else:
            logger.warn('Invalid key %s' % (key, ), terminal=True)
Exemplo n.º 13
0
def service_creator(daemon):
    assert isinstance(daemon, communicator.OnionrCommunicatorDaemon)
    
    # Find socket connection blocks
    # TODO cache blocks and only look at recently received ones
    con_blocks = blockmetadb.get_blocks_by_type('con')
    for b in con_blocks:
        if not b in daemon.active_services:
            bl = onionrblockapi.Block(b, decrypt=True)
            bs = bytesconverter.bytes_to_str(bl.bcontent) + '.onion'
            if server_exists(bl.signer):
                continue
            if stringvalidators.validate_pub_key(bl.signer) and stringvalidators.validate_transport(bs):
                signer = bytesconverter.bytes_to_str(bl.signer)
                daemon.active_services.append(b)
                daemon.active_services.append(signer)
                if not daemon.services.create_server(signer, bs, daemon):
                    daemon.active_services.remove(b)
                    daemon.active_services.remove(signer)
    daemon.decrementThreadCount('service_creator')
Exemplo n.º 14
0
    def isSigner(self, signer, encodedData=True):
        """
            Checks if the block was signed by the signer inputted

            Inputs:
            - signer (str): the public key of the signer to check against
            - encodedData (bool): whether or not the `signer` argument is base64 encoded

            Outputs:
            - (bool): whether or not the signer of the block is the signer inputted
        """
        signer = unpaddedbase32.repad(bytesconverter.str_to_bytes(signer))
        try:
            if (not self.isSigned()) or (
                    not stringvalidators.validate_pub_key(signer)):
                return False

            return bool(
                signing.ed_verify(self.getSignedData(),
                                  signer,
                                  self.getSignature(),
                                  encodedData=encodedData))
        except:
            return False
Exemplo n.º 15
0
def pub_key_decrypt(data, pubkey='', privkey='', encodedData=False):
    '''pubkey decrypt (Curve25519, taken from Ed25519 pubkey)'''
    if pubkey != '':
        pubkey = unpaddedbase32.repad(bytesconverter.str_to_bytes(pubkey))
    decrypted = False
    if encodedData:
        encoding = nacl.encoding.Base64Encoder
    else:
        encoding = nacl.encoding.RawEncoder
    if privkey == '':
        privkey = our_priv_key
    ownKey = nacl.signing.SigningKey(
        seed=privkey,
        encoder=nacl.encoding.Base32Encoder()).to_curve25519_private_key()

    if stringvalidators.validate_pub_key(privkey):
        privkey = nacl.signing.SigningKey(
            seed=privkey,
            encoder=nacl.encoding.Base32Encoder()).to_curve25519_private_key()
        anonBox = nacl.public.SealedBox(privkey)
    else:
        anonBox = nacl.public.SealedBox(ownKey)
    decrypted = anonBox.decrypt(data, encoder=encoding)
    return decrypted
Exemplo n.º 16
0
 def test_pub_from_priv(self):
     priv = nacl.signing.SigningKey.generate().encode(encoder=nacl.encoding.Base32Encoder)
     pub = crypto.cryptoutils.getpubfrompriv.get_pub_key_from_priv(priv)
     self.assertTrue(stringvalidators.validate_pub_key(pub))
Exemplo n.º 17
0
    def __init__(self, peer, address, comm_inst=None):

        if not stringvalidators.validate_pub_key(peer):
            raise ValueError('Peer must be valid base32 ed25519 public key')

        socks = config.get(
            'tor.socksport')  # Load config for Tor socks port for proxy
        service_app = Flask(__name__)  # Setup Flask app for server.
        service_port = get_open_port()
        service_ip = apiutils.setbindip.set_bind_IP()
        http_server = WSGIServer(('127.0.0.1', service_port),
                                 service_app,
                                 log=None)
        comm_inst.service_greenlets.append(http_server)
        key_store = simplekv.DeadSimpleKV(filepaths.cached_storage)

        # TODO define basic endpoints useful for direct connections like stats

        httpapi.load_plugin_blueprints(service_app,
                                       blueprint='direct_blueprint')

        @service_app.route('/ping')
        def get_ping():
            return "pong!"

        @service_app.route('/close')
        def shutdown_server():
            comm_inst.service_greenlets.remove(http_server)
            http_server.stop()
            return Response('goodbye')

        @service_app.after_request
        def afterReq(resp):
            # Security headers
            resp = httpheaders.set_default_onionr_http_headers(resp)
            return resp

        with Controller.from_port(
                port=config.get('tor.controlPort')) as controller:
            # Connect to the Tor process for Onionr
            controller.authenticate(config.get('tor.controlpassword'))
            # Create the v3 onion service for the peer to connect to
            response = controller.create_ephemeral_hidden_service(
                {80: service_port},
                await_publication=True,
                key_type='NEW',
                key_content='ED25519-V3')

            try:
                for x in range(3):
                    attempt = basicrequests.do_post_request(
                        'http://' + address + '/bs/' + response.service_id,
                        port=socks)
                    if attempt == 'success':
                        break
                else:
                    raise ConnectionError
            except ConnectionError:
                # Re-raise
                raise ConnectionError(
                    'Could not reach %s bootstrap address %s' %
                    (peer, address))
            else:
                # If no connection error, create the service and save it to local global key store
                peer = bytesconverter.bytes_to_str(peer)
                key_store.put('dc-' + peer, response.service_id)
                key_store.flush()
                logger.info('hosting on %s with %s' %
                            (response.service_id, peer))
                http_server.serve_forever()
                http_server.stop()
                key_store.delete('dc-' + peer)
Exemplo n.º 18
0
def insert_block(data: Union[str, bytes],
                 header: str = 'txt',
                 sign: bool = False,
                 encryptType: str = '',
                 symKey: str = '',
                 asymPeer: str = '',
                 meta: dict = {},
                 expire: Union[int, None] = None,
                 disableForward: bool = False,
                 signing_key: UserIDSecretKey = '') -> Union[str, bool]:
    """
    Create and insert a block into the network.

    encryptType must be specified to encrypt a block
    if expire is less than date, assumes seconds into future.
        if not assume exact epoch
    """
    our_private_key = crypto.priv_key
    our_pub_key = crypto.pub_key

    storage_counter = storagecounter.StorageCounter()

    allocationReachedMessage = 'Cannot insert block, disk allocation reached.'
    if storage_counter.is_full():
        logger.error(allocationReachedMessage)
        raise onionrexceptions.DiskAllocationReached

    if signing_key != '':
        # if it was specified to use an alternative private key
        our_private_key = signing_key
        our_pub_key = bytesconverter.bytes_to_str(
            crypto.cryptoutils.get_pub_key_from_priv(our_private_key))

    retData = False

    if type(data) is None:
        raise ValueError('Data cannot be none')

    createTime = epoch.get_epoch()

    dataNonce = bytesconverter.bytes_to_str(crypto.hashers.sha3_hash(data))
    try:
        with open(filepaths.data_nonce_file, 'r') as nonces:
            if dataNonce in nonces:
                return retData
    except FileNotFoundError:
        pass
    # record nonce
    with open(filepaths.data_nonce_file, 'a') as nonceFile:
        nonceFile.write(dataNonce + '\n')

    plaintext = data
    plaintextMeta = {}
    plaintextPeer = asymPeer

    retData = ''
    signature = ''
    signer = ''
    metadata = {}

    # metadata is full block metadata
    # meta is internal, user specified metadata

    # only use header if not set in provided meta

    meta['type'] = str(header)

    if encryptType in ('asym', 'sym'):
        metadata['encryptType'] = encryptType
    else:
        if not config.get('general.store_plaintext_blocks', True):
            raise onionrexceptions.InvalidMetadata(
                "Plaintext blocks are disabled, " +
                "yet a plaintext block was being inserted")
        if encryptType not in ('', None):
            raise onionrexceptions.InvalidMetadata(
                'encryptType must be asym or sym, or blank')

    try:
        data = data.encode()
    except AttributeError:
        pass

    if encryptType == 'asym':
        # Duplicate the time in encrypted messages to help prevent replays
        meta['rply'] = createTime
        if sign and asymPeer != our_pub_key:
            try:
                forwardEncrypted = onionrusers.OnionrUser(
                    asymPeer).forwardEncrypt(data)
                data = forwardEncrypted[0]
                meta['forwardEnc'] = True
                # Expire time of key. no sense keeping block after that
                expire = forwardEncrypted[2]
            except onionrexceptions.InvalidPubkey:
                pass
            if not disableForward:
                fsKey = onionrusers.OnionrUser(asymPeer).generateForwardKey()
                meta['newFSKey'] = fsKey
    jsonMeta = json.dumps(meta)
    plaintextMeta = jsonMeta
    if sign:
        signature = crypto.signing.ed_sign(jsonMeta.encode() + data,
                                           key=our_private_key,
                                           encodeResult=True)
        signer = our_pub_key

    if len(jsonMeta) > 1000:
        raise onionrexceptions.InvalidMetadata(
            'meta in json encoded form must not exceed 1000 bytes')

    # encrypt block metadata/sig/content
    if encryptType == 'sym':
        raise NotImplementedError("not yet implemented")
    elif encryptType == 'asym':
        if stringvalidators.validate_pub_key(asymPeer):
            # Encrypt block data with forward secrecy key first, but not meta
            jsonMeta = json.dumps(meta)
            jsonMeta = crypto.encryption.pub_key_encrypt(
                jsonMeta, asymPeer, encodedData=True).decode()
            data = crypto.encryption.pub_key_encrypt(data,
                                                     asymPeer,
                                                     encodedData=False)
            signature = crypto.encryption.pub_key_encrypt(
                signature, asymPeer, encodedData=True).decode()
            signer = crypto.encryption.pub_key_encrypt(
                signer, asymPeer, encodedData=True).decode()
            try:
                onionrusers.OnionrUser(asymPeer, saveUser=True)
            except ValueError:
                # if peer is already known
                pass
        else:
            raise onionrexceptions.InvalidPubkey(
                asymPeer + ' is not a valid base32 encoded ed25519 key')

    # compile metadata
    metadata['meta'] = jsonMeta
    if len(signature) > 0:  # I don't like not pattern
        metadata['sig'] = signature
        metadata['signer'] = signer
    metadata['time'] = createTime

    # ensure expire is integer and of sane length
    if type(expire) is not type(None):  # noqa
        if not len(str(int(expire))) < 20:
            raise ValueError(
                'expire must be valid int less than 20 digits in length')
        # if expire is less than date, assume seconds into future
        if expire < epoch.get_epoch():
            expire = epoch.get_epoch() + expire
        metadata['expire'] = expire

    # send block data (and metadata) to POW module to get tokenized block data
    payload = subprocesspow.SubprocessPOW(data, metadata).start()
    if payload != False:  # noqa
        try:
            retData = onionrstorage.set_data(payload)
        except onionrexceptions.DiskAllocationReached:
            logger.error(allocationReachedMessage)
            retData = False
        else:
            if disableForward:
                logger.warn(
                    f'{retData} asym encrypted block created w/o ephemerality')
            """
            Tell the api server through localCommand to wait for the daemon to
            upload this block to make statistical analysis more difficult
            """
            spawn(localcommand.local_command,
                  '/daemon-event/upload_event',
                  post=True,
                  is_json=True,
                  post_data={
                      'block': retData
                  }).get(timeout=5)
            coredb.blockmetadb.add.add_to_block_DB(retData,
                                                   selfInsert=True,
                                                   dataSaved=True)

            if expire is None:
                coredb.blockmetadb.update_block_info(
                    retData, 'expire', createTime + min(
                        onionrvalues.DEFAULT_EXPIRE,
                        config.get('general.max_block_age',
                                   onionrvalues.DEFAULT_EXPIRE)))
            else:
                coredb.blockmetadb.update_block_info(retData, 'expire', expire)

            blockmetadata.process_block_metadata(retData)

    if retData != False:  # noqa
        if plaintextPeer == onionrvalues.DENIABLE_PEER_ADDRESS:
            events.event('insertdeniable', {
                'content': plaintext,
                'meta': plaintextMeta,
                'hash': retData,
                'peer': bytesconverter.bytes_to_str(asymPeer)
            },
                         threaded=True)
        else:
            events.event('insertblock', {
                'content': plaintext,
                'meta': plaintextMeta,
                'hash': retData,
                'peer': bytesconverter.bytes_to_str(asymPeer)
            },
                         threaded=True)

    spawn(localcommand.local_command,
          '/daemon-event/remove_from_insert_queue_wrapper',
          post=True,
          post_data={
              'block_hash': retData
          },
          is_json=True).get(timeout=5)
    return retData
Exemplo n.º 19
0
def bootstrap_client_service(peer, comm_inst=None, bootstrap_timeout=300):
    '''
        Bootstrap client services
    '''
    if not stringvalidators.validate_pub_key(peer):
        raise ValueError('Peer must be valid base32 ed25519 public key')

    connection_pool = None

    # here we use a lambda for the timeout thread to set to true
    timed_out = lambda: None
    timed_out.timed_out = False

    bootstrap_port = get_open_port()
    bootstrap_app = Flask(__name__)
    bootstrap_app.config['MAX_CONTENT_LENGTH'] = 1 * 1024

    http_server = WSGIServer(('127.0.0.1', bootstrap_port),
                             bootstrap_app,
                             log=None)
    try:
        if comm_inst is None: raise ValueError
    except (AttributeError, ValueError) as e:
        pass
    else:
        comm_inst.service_greenlets.append(http_server)
        connection_pool = comm_inst.shared_state.get(pool.ServicePool)

    bootstrap_address = ''
    shutdown = False
    bs_id = str(uuid.uuid4())
    key_store = simplekv.DeadSimpleKV(filepaths.cached_storage)

    @bootstrap_app.route('/ping')
    def get_ping():
        return "pong!"

    @bootstrap_app.after_request
    def afterReq(resp):
        # Security headers
        resp = httpheaders.set_default_onionr_http_headers(resp)
        return resp

    @bootstrap_app.route('/bs/<address>', methods=['POST'])
    def get_bootstrap(address):
        if stringvalidators.validate_transport(address + '.onion'):
            # Set the bootstrap address then close the server
            bootstrap_address = address + '.onion'
            key_store.put(bs_id, bootstrap_address)
            http_server.stop()
            return Response("success")
        else:
            return Response("")

    with Controller.from_port(
            port=config.get('tor.controlPort')) as controller:
        if not connection_pool is None:
            connection_pool.bootstrap_pending.append(peer)
        # Connect to the Tor process for Onionr
        controller.authenticate(config.get('tor.controlpassword'))
        # Create the v3 onion service
        response = controller.create_ephemeral_hidden_service(
            {80: bootstrap_port},
            key_type='NEW',
            key_content='ED25519-V3',
            await_publication=True)
        onionrblocks.insert(response.service_id,
                            header='con',
                            sign=True,
                            encryptType='asym',
                            asymPeer=peer,
                            disableForward=True,
                            expire=(epoch.get_epoch() + bootstrap_timeout))

        threading.Thread(target=__bootstrap_timeout,
                         args=[http_server, bootstrap_timeout, timed_out],
                         daemon=True).start()

        # Run the bootstrap server
        try:
            http_server.serve_forever()
        except TypeError:
            pass
        # This line reached when server is shutdown by being bootstrapped
    # Add the address to the client pool
    if not comm_inst is None:
        connection_pool.bootstrap_pending.remove(peer)
        if timed_out.timed_out:
            logger.warn('Could not connect to %s due to timeout' % (peer, ))
            return None
        comm_inst.direct_connection_clients[peer] = response.service_id

    # Now that the bootstrap server has received a server, return the address
    return key_store.get(bs_id)
Exemplo n.º 20
0
 def test_sane_default(self):
     self.assertGreaterEqual(len(pub_key), 52)
     self.assertLessEqual(len(pub_key), 56)
     self.assertEqual(pub_key, keymanager.KeyManager().getPubkeyList()[0])
     stringvalidators.validate_pub_key(pub_key)
Exemplo n.º 21
0
 def valid_default_id(self):
     self.assertTrue(stringvalidators.validate_pub_key(crypto.pub_key))
Exemplo n.º 22
0
 def test_change(self):
     new_key = keymanager.KeyManager().addKey()[0]
     self.assertNotEqual(new_key, pub_key)
     self.assertEqual(new_key, keymanager.KeyManager().getPubkeyList()[1])
     stringvalidators.validate_pub_key(new_key)