Beispiel #1
0
def test_sign_test_key_conversion():
    """
    Taken from test vectors in libsodium
    """
    keypair_seed = unhexlify(b"421151a459faeade3d247115f94aedae"
                             b"42318124095afabe4d1451a559faedee")
    ed25519_pk, ed25519_sk = c.crypto_sign_seed_keypair(keypair_seed)

    assert c.crypto_sign_ed25519_sk_to_pk(ed25519_sk) == ed25519_pk
    with pytest.raises(ValueError):
        c.crypto_sign_ed25519_sk_to_pk(unhexlify(b"12"))

    assert c.crypto_sign_ed25519_sk_to_seed(ed25519_sk) == keypair_seed
    with pytest.raises(ValueError):
        c.crypto_sign_ed25519_sk_to_seed(unhexlify(b"12"))

    curve25519_pk = c.crypto_sign_ed25519_pk_to_curve25519(ed25519_pk)

    with pytest.raises(ValueError):
        c.crypto_sign_ed25519_pk_to_curve25519(unhexlify(b"12"))
    with pytest.raises(ValueError):
        c.crypto_sign_ed25519_sk_to_curve25519(unhexlify(b"12"))

    curve25519_sk = c.crypto_sign_ed25519_sk_to_curve25519(ed25519_sk)

    assert tohex(curve25519_pk) == ("f1814f0e8ff1043d8a44d25babff3ced"
                                    "cae6c22c3edaa48f857ae70de2baae50")
    assert tohex(curve25519_sk) == ("8052030376d47112be7f73ed7a019293"
                                    "dd12ad910b654455798b4667d73de166")
Beispiel #2
0
def test_sign_test_key_conversion():
    """
    Taken from test vectors in libsodium
    """
    keypair_seed = unhexlify(b"421151a459faeade3d247115f94aedae"
                             b"42318124095afabe4d1451a559faedee")
    ed25519_pk, ed25519_sk = c.crypto_sign_seed_keypair(keypair_seed)

    assert c.crypto_sign_ed25519_sk_to_pk(ed25519_sk) == ed25519_pk
    with pytest.raises(ValueError):
        c.crypto_sign_ed25519_sk_to_pk(unhexlify(b"12"))

    assert c.crypto_sign_ed25519_sk_to_seed(ed25519_sk) == keypair_seed
    with pytest.raises(ValueError):
        c.crypto_sign_ed25519_sk_to_seed(unhexlify(b"12"))

    curve25519_pk = c.crypto_sign_ed25519_pk_to_curve25519(ed25519_pk)

    with pytest.raises(ValueError):
        c.crypto_sign_ed25519_pk_to_curve25519(unhexlify(b"12"))
    with pytest.raises(ValueError):
        c.crypto_sign_ed25519_sk_to_curve25519(unhexlify(b"12"))

    curve25519_sk = c.crypto_sign_ed25519_sk_to_curve25519(ed25519_sk)

    assert tohex(curve25519_pk) == ("f1814f0e8ff1043d8a44d25babff3ced"
                                    "cae6c22c3edaa48f857ae70de2baae50")
    assert tohex(curve25519_sk) == ("8052030376d47112be7f73ed7a019293"
                                    "dd12ad910b654455798b4667d73de166")
Beispiel #3
0
 def get_remote_feed(self):
     remote_feed = None
     if os.path.isfile(CONFIG_DIR + self.remote_fid + ".pcap"):
         remote_feed = FEED(CONFIG_DIR + self.remote_fid + ".pcap",
                            bytes.fromhex(self.remote_fid),
                            PublicKey(crypto_sign_ed25519_pk_to_curve25519(bytes.fromhex(self.remote_fid))))
     return remote_feed
Beispiel #4
0
 def get_remote_data_feed(self):
     remote_feed = None
     if self.get_data_feed() is not None:
         if os.path.isfile( DATA_DIR + self.get_data_feed() + ".pcap"):
             remote_feed = FEED(DATA_DIR + self.get_data_feed() + ".pcap",
                                bytes.fromhex(self.get_data_feed()),
                                PublicKey(crypto_sign_ed25519_pk_to_curve25519(bytes.fromhex(self.get_data_feed()))))
     return remote_feed
Beispiel #5
0
    def add_verifying_key(self, vk: str):
        # Convert to bytes if hex string
        bvk = bytes.fromhex(vk)

        try:
            pk = crypto_sign_ed25519_pk_to_curve25519(bvk)
        # Error is thrown if the VK is not within the possibility space of the ED25519 algorithm
        except RuntimeError:
            self.log.error('ED25519 Cryptographic error. The key provided is not within the cryptographic key space.')
            return

        zvk = z85.encode(pk).decode('utf-8')
        _write_key_file(self.cert_dir / f'{vk}.key', banner=_cert_public_banner, public_key=zvk)
    def add_verifying_key(self, vk: bytes):
        # Convert to bytes if hex string
        if isinstance(vk, str):
            vk = bytes.fromhex(vk)

        try:
            pk = crypto_sign_ed25519_pk_to_curve25519(vk)
        # Error is thrown if the VK is not within the possibility space of the ED25519 algorithm
        except RuntimeError:
            print('no go')
            return

        zvk = z85.encode(pk).decode('utf-8')
        _write_key_file(self.cert_dir / f'{vk.hex()}.key',
                        banner=_cert_public_banner,
                        public_key=zvk)
Beispiel #7
0
    def bacnet_watchdog(self):
        old_seq = {}
        self.tcp_threads = {}
        for authorized_feed in self.authorized_feeds:
            old_seq[authorized_feed] = -1

        while True:
            for authorized_feed in self.authorized_feeds:
                if os.path.isfile(authorized_feed + ".pcap"):
                    temp_feed = FEED(authorized_feed + ".pcap",
                                     bytes.fromhex(authorized_feed),
                                     PublicKey(crypto_sign_ed25519_pk_to_curve25519(bytes.fromhex(authorized_feed))))
                    if old_seq[authorized_feed] != temp_feed.seq and old_seq[authorized_feed] >= 0:
                        temp_feed.seq = 0
                        temp_feed.hprev = None
                        for e in temp_feed:
                            if not temp_feed.is_valid_extension(e):
                                print(f"-> event {temp_feed.seq + 1}: chaining or signature problem")
                            else:
                                if temp_feed.seq == old_seq[authorized_feed]:

                                    e_content = json.loads(e.content())
                                    if e_content['event'] == "tcp/open":
                                        host = e_content['content']['host']
                                        port = int(e_content['content']['port'])
                                        self.setup_data_feed(authorized_feed)

                                        if not authorized_feed in self.tcp_threads.keys():
                                            self.tcp_threads[authorized_feed] = {}
                                            self.tcp_threads[authorized_feed]['tasks'] = queue.Queue()
                                            self.tcp_threads[authorized_feed]['thread'] = Thread(
                                                target=self.tcp_watchdog,
                                                args=(authorized_feed, host, port))
                                            self.tcp_threads[authorized_feed]['thread'].start()
                                    elif e_content['event'] == "tcp/write":
                                        if authorized_feed in self.tcp_threads.keys():
                                            self.tcp_threads[authorized_feed]['tasks'].put(e_content)
                                    elif e_content['event'] == "tcp/close":
                                        if authorized_feed in self.tcp_threads.keys():
                                            self.tcp_threads[authorized_feed]['tasks'].put(e_content)
                            if old_seq[authorized_feed] < temp_feed.seq:
                                break
                            temp_feed.seq += 1
                            temp_feed.hprev = e.get_ref()
                    old_seq[authorized_feed] = temp_feed.seq
            time.sleep(1)
Beispiel #8
0
    def write_to(self, channel: CHANNEL, event, content, r=None, rekey=0):
        """
        This function creates a write statement after encrypting the message.

        Parameters
        ----------
        self : USER
            The user who writes
        channel : CHANNEL
            The channel where user writes to
        event: EVENT
            The event to write
        content: str
            The content of the event
        r: String
            The public key of the recipient user
        rekey: int
            Indicates which dkey to use (0 = latest, 1 = one before latest, ...)
        """
        # no rekey
        if r != None:
            # create a box between owner of a channel and invited user
            box = Box(
                self.get_curve_private_key(),
                PublicKey(
                    crypto_sign_ed25519_pk_to_curve25519(bytes.fromhex(r))))
            hkey = bytes.fromhex(self.fid)
        # rekey necessary
        else:
            # create a box containing all members of a channel
            box = SecretBox(channel.dkeys_bytes()[rekey])
            hkey = channel.hkey_bytes()
        # build message from event and content and encrypt it
        message = get_message_json(event, content).encode('utf-8')
        encrypted = box.encrypt(message, encoder=Base64Encoder)

        # write cyphertext using digest (=cypher) and encrypted message
        digest = hmac.digest(hkey, encrypted, sha256)
        self.write_cyphertext(digest, encrypted)
Beispiel #9
0
 def to_age_public_key(self) -> AgePublicKey:
     # use pynacl for this conversion
     ed25519_pk = self._key.public_bytes(Encoding.Raw, PublicFormat.Raw)
     curve25519_pk = crypto_sign_ed25519_pk_to_curve25519(ed25519_pk)
     public_key = X25519PublicKey.from_public_bytes(curve25519_pk)
     return AgePublicKey(public_key)
Beispiel #10
0
    def sync(self):
        """
        This function completes a synchronization process of a user
        which gets the updates of the users he follows.

        Parameters
        ----------
        self : USER
            The user which does a sync
        """
        synced = {}
        f = FEED("user-" + self.fid + '.pcap', bytes.fromhex(self.fid),
                 self.get_signer())
        if f.pcap == None:
            return
        f.seq = 0
        f.hprev = None
        # print(f"Checking feed {f.fid.hex()}")
        for e in f:
            # print(e)
            if not f.is_valid_extension(e):
                print(f"-> event {f.seq + 1}: chaining or signature problem")
            else:
                event = check_sync(e.content())
                if (event != None):
                    synced[event.fid.hex()] = event.seq

            f.seq += 1
            f.hprev = e.get_ref()
        # print(synced)

        # iterate through the users he follows
        for follow in self.follows:
            f = FEED(
                "user-" + follow + '.pcap', bytes.fromhex(follow),
                PublicKey(
                    crypto_sign_ed25519_pk_to_curve25519(
                        bytes.fromhex(follow))))
            if f.pcap == None:
                exit(1)
            f.seq = 0
            f.hprev = None
            # print(f"Checking feed {f.fid.hex()}")
            new_msg_count = 0
            # iterate through events in their feeds
            for e in f:
                # print(e)
                # event not valid
                if not f.is_valid_extension(e):
                    print(
                        f"-> event {f.seq + 1}: chaining or signature problem")
                # event valid
                else:
                    try:
                        syncremote = synced[follow]
                    except:
                        syncremote = -1
                    # if this event is not synced yet
                    if (syncremote < e.seq):
                        # remember that we have synced this
                        synced[follow] = e.seq
                        eo = e
                        ev = check_sync(e.content())
                        # if it's a sync entry
                        if (ev != None):
                            # ignore the ones from our log
                            if (ev.fid.hex() == self.fid):
                                f.seq += 1
                                f.hprev = e.get_ref()
                                continue
                            try:
                                # get sync progress of this synced event
                                syncdeep = synced[ev.fid.hex()]
                            except:
                                syncdeep = -1
                            # ignore everything not newer
                            if (ev.seq <= syncdeep):
                                f.seq += 1
                                f.hprev = e.get_ref()
                                continue
                            # remember that we have synced this
                            synced[ev.fid.hex()] = ev.seq
                            eo = ev
                        # write cleartext to log oof sync process
                        self.write_cleartext(
                            get_message_json("log/sync", eo.wire.hex()))
                        new_msg_count += 1
                        self.decrypt(eo, parse=True)
                        # print("add:",eo.seq,self.getFollowAlias(eo.fid.hex()))
                # go to next event in feed
                f.seq += 1
                f.hprev = e.get_ref()
            """ if (new_msg_count > 0):
Beispiel #11
0
    def decrypt(self, event: EVENT, parse=False):
        """
        Using this function a user tries to decrypt an event.

        Parameters
        ----------
        self : USER
            The user decrypting an event
        event : EVENT
            The event to decrypt
        parse : bool
            Describes if event need to be parsed
        """
        # msg = '{"event": "app/action", "content": "xxx"}'
        # log_event = '{"hmac": "'+digest.hex()+'", "cyphertext": "'+encrypted.hex()+'"}'
        # log_event = {"cleartext": {"event": "chat/create", "content": "two"}}
        # log_event = {"cleartext": {"event": "log/sync", "content": "RAW_BACNET_EVENT"}}
        # print(event)

        # determine sender
        sender = get_alias_by_id(self.fid)
        # check if need to sync
        e = check_sync(event.content())
        if (e != None):
            # parse this content
            event = e
            sender = get_alias_by_id(e.fid.hex())
            # return 'sync: ' + e.fid.hex() + ' ' + e.content().__repr__()
        data = loads(event.content())

        try:
            # print cleartext
            return sender + '@all: ' + data['cleartext']['event'] + ' ' + data[
                'cleartext']['content']
        except KeyError:
            # cyphertext --> needs decryption
            cypher = bytes.fromhex(data['cyphertext'])
            if bytes.fromhex(data['hmac']) == hmac.digest(
                    event.fid, cypher, sha256):
                try:
                    # try to decrypt private event
                    box = Box(
                        self.get_curve_private_key(),
                        PublicKey(
                            crypto_sign_ed25519_pk_to_curve25519(event.fid)))
                    cleartext = box.decrypt(cypher, encoder=Base64Encoder)
                    data = loads(cleartext)
                    inv = check_invite(data)
                    if parse and inv != None:
                        self.add_channel(inv)
                    return sender + '@private: ' + data['event'] + ' ' + data[
                        'content']
                except nacl.exceptions.CryptoError:
                    # not allowed to decrypt private boy
                    return sender + '@privatebox'
            # loop through other channels hkey
            for c in self.channels:
                c = CHANNEL(self, c[0])
                channel = get_alias_by_id(c.cid)
                hkey = c.hkey_bytes()
                if bytes.fromhex(data['hmac']) == hmac.digest(
                        hkey, cypher, sha256):
                    # print('matched hkey: '+hkey)
                    # print('hmac: '+data['hmac'])
                    # print('unboxing...')
                    for dk in c.dkeys_bytes():
                        try:
                            # decrypt message in channel
                            box = SecretBox(dk)
                            cleartext = box.decrypt(cypher,
                                                    encoder=Base64Encoder)
                            data = loads(cleartext)
                            rekey = check_rekey(data)
                            if parse and rekey != None:
                                c.add_dkey(self, rekey)
                            return sender + '@[' + channel + ']: ' + data[
                                'event'] + ' ' + data['content']
                        except nacl.exceptions.CryptoError:
                            # not allowed to decrypt channel message
                            continue  # perhaps there is another dkey
                    return sender + '@lock[' + channel + ']'  # no dkey found (not a member anymore)
            return sender + '@secret'  # - not cleartext nor matching a channel