Ejemplo n.º 1
0
async def main():
    try:
        timestamp = ndn.utils.timestamp()
        name = Name.from_str('/example/testApp/randomData') + [
            Component.from_timestamp(timestamp)
        ]
        print(
            f'Sending Interest {Name.to_str(name)}, {InterestParam(must_be_fresh=True, lifetime=6000)}'
        )
        data_name, meta_info, content = await app.express_interest(
            name, must_be_fresh=True, can_be_prefix=False, lifetime=6000)

        print(f'Received Data Name: {Name.to_str(data_name)}')
        print(meta_info)
        print(bytes(content) if content else None)
    except InterestNack as e:
        print(f'Nacked with reason={e.reason}')
    except InterestTimeout:
        print(f'Timeout')
    except InterestCanceled:
        print(f'Canceled')
    except ValidationFailure:
        print(f'Data failed to validate')
    finally:
        app.shutdown()
Ejemplo n.º 2
0
async def get_last_frame(device_name):
    """
    Get the last frame number from interest /device/1080p/metadata/timestamp
    """
    message_counter = 0
    while message_counter < 100:
        try:
            timestamp = ndn.utils.timestamp()
            name = Name.from_str('/{}/1080p/metadata/'.format(device_name)) + [
                Component.from_timestamp(timestamp)
            ]
            print(
                f'Sending Interest {Name.to_str(name)}, {InterestParam(must_be_fresh=False, lifetime=600)}'
            )
            data_name, meta_info, content = await app.express_interest(
                name, must_be_fresh=False, can_be_prefix=True, lifetime=2000)
            print(f'Received Data Name: {Name.to_str(data_name)}')
            ct = bytes(content)
            last_frame_name = Name.from_str(str(ct)[2:-1])
            print("Last Frame number ", Name.to_str(last_frame_name))
            last_frame_num = Component.to_number(last_frame_name[-1])
            return last_frame_num
        except InterestNack as e:
            print(f'Nacked with reason={e.reason}')
        except InterestTimeout:
            print(f'Timeout')
        except InterestCanceled:
            print(f'Canceled')
        except ValidationFailure:
            print(f'Data failed to validate')
        message_counter += 1
Ejemplo n.º 3
0
    def ref_list(self, name: FormalName, _param: InterestParam, _app_param: typing.Optional[BinaryStr]):
        ref_heads = self.repo.get_ref_heads()
        result = '\n'.join(f'{head.hex()} {ref}' for ref, head in ref_heads.items())
        result += '\n'
        logging.debug(f'On ref-list: {repr(result)}')

        data_name = name + [Component.from_timestamp(timestamp())]
        self.app.put_data(data_name, result.encode(), freshness_period=1000)
Ejemplo n.º 4
0
async def main():
    try:
        # Get the public key
        pub_key = bytes([
            0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
            0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
            0x00, 0xb8, 0x09, 0xa7, 0x59, 0x82, 0x84, 0xec, 0x4f, 0x06, 0xfa, 0x1c, 0xb2, 0xe1, 0x38, 0x93,
            0x53, 0xbb, 0x7d, 0xd4, 0xac, 0x88, 0x1a, 0xf8, 0x25, 0x11, 0xe4, 0xfa, 0x1d, 0x61, 0x24, 0x5b,
            0x82, 0xca, 0xcd, 0x72, 0xce, 0xdb, 0x66, 0xb5, 0x8d, 0x54, 0xbd, 0xfb, 0x23, 0xfd, 0xe8, 0x8e,
            0xaf, 0xa7, 0xb3, 0x79, 0xbe, 0x94, 0xb5, 0xb7, 0xba, 0x17, 0xb6, 0x05, 0xae, 0xce, 0x43, 0xbe,
            0x3b, 0xce, 0x6e, 0xea, 0x07, 0xdb, 0xbf, 0x0a, 0x7e, 0xeb, 0xbc, 0xc9, 0x7b, 0x62, 0x3c, 0xf5,
            0xe1, 0xce, 0xe1, 0xd9, 0x8d, 0x9c, 0xfe, 0x1f, 0xc7, 0xf8, 0xfb, 0x59, 0xc0, 0x94, 0x0b, 0x2c,
            0xd9, 0x7d, 0xbc, 0x96, 0xeb, 0xb8, 0x79, 0x22, 0x8a, 0x2e, 0xa0, 0x12, 0x1d, 0x42, 0x07, 0xb6,
            0x5d, 0xdb, 0xe1, 0xf6, 0xb1, 0x5d, 0x7b, 0x1f, 0x54, 0x52, 0x1c, 0xa3, 0x11, 0x9b, 0xf9, 0xeb,
            0xbe, 0xb3, 0x95, 0xca, 0xa5, 0x87, 0x3f, 0x31, 0x18, 0x1a, 0xc9, 0x99, 0x01, 0xec, 0xaa, 0x90,
            0xfd, 0x8a, 0x36, 0x35, 0x5e, 0x12, 0x81, 0xbe, 0x84, 0x88, 0xa1, 0x0d, 0x19, 0x2a, 0x4a, 0x66,
            0xc1, 0x59, 0x3c, 0x41, 0x83, 0x3d, 0x3d, 0xb8, 0xd4, 0xab, 0x34, 0x90, 0x06, 0x3e, 0x1a, 0x61,
            0x74, 0xbe, 0x04, 0xf5, 0x7a, 0x69, 0x1b, 0x9d, 0x56, 0xfc, 0x83, 0xb7, 0x60, 0xc1, 0x5e, 0x9d,
            0x85, 0x34, 0xfd, 0x02, 0x1a, 0xba, 0x2c, 0x09, 0x72, 0xa7, 0x4a, 0x5e, 0x18, 0xbf, 0xc0, 0x58,
            0xa7, 0x49, 0x34, 0x46, 0x61, 0x59, 0x0e, 0xe2, 0x6e, 0x9e, 0xd2, 0xdb, 0xfd, 0x72, 0x2f, 0x3c,
            0x47, 0xcc, 0x5f, 0x99, 0x62, 0xee, 0x0d, 0xf3, 0x1f, 0x30, 0x25, 0x20, 0x92, 0x15, 0x4b, 0x04,
            0xfe, 0x15, 0x19, 0x1d, 0xdc, 0x7e, 0x5c, 0x10, 0x21, 0x52, 0x21, 0x91, 0x54, 0x60, 0x8b, 0x92,
            0x41, 0x02, 0x03, 0x01, 0x00, 0x01
        ])
        if pub_key is None:
            timestamp = ndn.utils.timestamp()
            name = Name.from_str('/edge/KEY/000') + [Component.from_timestamp(timestamp)]
            print(f'Sending Interest {Name.to_str(name)}, {InterestParam(must_be_fresh=True, lifetime=6000)}')
            data_name, meta_info, content = await app.express_interest(
                name, must_be_fresh=True, can_be_prefix=False, lifetime=6000)
            pub_key = bytes(content)
            logging.debug("Get public key from the server")
        app.pub_key = pub_key

        timestamp = ndn.utils.timestamp()
        # name = Name.from_str('/example/testApp/randomData') + [Component.from_timestamp(timestamp)]
        name = Name.from_str('/testecho/1080p/frame/P/20')
        print(f'Sending Interest {Name.to_str(name)}')
        # data_name, meta_info, content = await app.express_interest(
        #     name, must_be_fresh=True, can_be_prefix=False, lifetime=6000)
        data_name, meta_info, content = await app.express_interest(
            name, must_be_fresh=False, can_be_prefix=True, lifetime=2000)

        print(f'Received Data Name: {Name.to_str(data_name)}')
        print(meta_info)
        print(bytes(content) if content else None)
    except InterestNack as e:
        print(f'Nacked with reason={e.reason}')
    except InterestTimeout:
        print(f'Timeout')
    except InterestCanceled:
        print(f'Canceled')
    except ValidationFailure:
        print(f'Data failed to validate')
    finally:
        app.shutdown()
Ejemplo n.º 5
0
 def test_number():
     assert Component.from_segment(13) == b'!\x01\r'
     assert Component.from_byte_offset(13) == b'\x22\x01\r'
     assert Component.from_sequence_num(13) == b'%\x01\r'
     assert Component.from_version(13) == b'#\x01\r'
     timeval = 15686790223318112
     comp = Component.from_timestamp(timeval)
     assert Component.get_type(comp) == 36
     assert Component.get_value(comp) == b'\x00\x37\xbb\x0d\x76\xed\x4c\x60'
     assert Component.to_number(comp) == timeval
Ejemplo n.º 6
0
    def test_number():
        assert Component.from_segment(13) == b'!\x01\r'
        assert Component.from_byte_offset(13) == b'\x22\x01\r'
        assert Component.from_sequence_num(13) == b'%\x01\r'
        assert Component.from_version(13) == b'#\x01\r'
        timeval = 15686790223318112
        comp = Component.from_timestamp(timeval)
        assert Component.get_type(comp) == 36
        assert Component.get_value(comp) == b'\x00\x37\xbb\x0d\x76\xed\x4c\x60'
        assert Component.to_number(comp) == timeval

        assert Component.to_str(Component.from_segment(13)) == 'seg=13'
        assert Component.to_str(Component.from_byte_offset(13)) == 'off=13'
        assert Component.to_str(Component.from_sequence_num(13)) == 'seq=13'
        assert Component.to_str(Component.from_version(13)) == 'v=13'
        assert Component.to_str(
            Component.from_timestamp(timeval)) == 't=15686790223318112'

        assert Component.from_str('seg=13') == b'!\x01\r'
        assert Component.from_str('off=13') == b'\x22\x01\r'
        assert Component.from_str('seq=13') == b'%\x01\r'
        assert Component.from_str('v=13') == b'#\x01\r'
        assert Component.from_str(
            't=15686790223318112') == b'$\x08\x007\xbb\rv\xedL`'
Ejemplo n.º 7
0
async def main():
    global local_anchor

    import_safebag("sec/client.safebag", "1234")

    # parse again to read prv key into memory 
    request = CertRequest()
    with open("sec/client.safebag", "r") as safebag:
        wire = safebag.read()
        wire = base64.b64decode(wire)
        wire = parse_and_check_tl(wire, SecurityV2TypeNumber.SAFE_BAG)
        bag = SafeBag.parse(wire)

        # attach the testbed-signed certificate
        request.testbed_signed = bag.certificate_v2

        # parse the key bag to obtain private key
        testbed_signed = CertificateV2Value.parse(bag.certificate_v2)
        key_bag = bytes(bag.encrypted_key_bag)
        privateKey = serialization.load_der_private_key(key_bag, password=b'1234', backend=default_backend())
        client_prv_key = privateKey.private_bytes(Encoding.DER, PrivateFormat.PKCS8, NoEncryption())

    # parse trust anchor and self-assigns a name, then create self-signed certificate
    with open("sec/client.anchor", "r") as anchor:
        wire = anchor.read()
        wire = base64.b64decode(wire)
        local_anchor = parse_certificate(wire)

        # self-assign a name and create corresponding key pair
        client_name = local_anchor.name[:-4] + [testbed_signed.name[-5]]
        client_identity = app.keychain.touch_identity(client_name)

        # attach newly generated self-assigned certificate
        cert = client_identity.default_key().default_cert().data
        cert = parse_certificate(cert)
        request.self_signed = cert.encode()

    try:
        # express the first interest to fetch a token/secret code
        timestamp = ndn.utils.timestamp()
        name = Name.from_str('/edge/_ca/new-cert') + [Component.from_timestamp(timestamp)]
        logging.info(f'Sending Interest {Name.to_str(name)}, {InterestParam(must_be_fresh=True, lifetime=6000)}')
        data_name, meta_info, content = await app.express_interest(
            name, app_param=request.encode(), must_be_fresh=True, can_be_prefix=False, lifetime=6000,
            identity=client_identity, validator=verify_ecdsa_signature)
        
        # sign it use the private key, to prove the certificate possesion
        h = SHA256.new()
        h.update(bytes(content))
        pk = ECC.import_key(client_prv_key)
        signature = DSS.new(pk, 'fips-186-3', 'der').sign(h)
        logging.info(f'Getting Data {Name.to_str(name)}, begin signing the token {bytes(content)}')

        # express the second interest to fetch the issued certificate
        name = Name.from_str('/edge/_ca/challenge') + [Component.from_timestamp(timestamp)]
        logging.info(f'Sending Interest {Name.to_str(name)}, {InterestParam(must_be_fresh=True, lifetime=6000)}')
        data_name, meta_info, content = await app.express_interest(
            name, app_param=signature, must_be_fresh=True, can_be_prefix=False, lifetime=6000, 
            identity=client_identity, validator=verify_ecdsa_signature)

        # parse the issued certificate and install
        issued_cert = parse_certificate(content)
        logging.info("Issued certificate: %s", Name.to_str(issued_cert.name))
        app.keychain.import_cert(Name.to_bytes(issued_cert.name[:-2]), Name.to_bytes(issued_cert.name), bytes(content))

    except InterestNack as e:
        print(f'Nacked with reason={e.reason}')
    except InterestTimeout:
        print(f'Timeout')
    except InterestCanceled:
        print(f'Canceled')
    except ValidationFailure:
        print(f'Data failed to validate')
        app.shutdown()
Ejemplo n.º 8
0
    async def use_service(self, service: str, is_cmd: str, name_or_cmd: str,
                          param: str):
        """
        Use NDN-LITE service
            cmd interest name: /home/SERVICE/CMD/room/device-id/command
            notification interest name: /home/SERVICE/NOTIFY/CMD/room/device-id/command
            data fetching name: /home/SERVICE/DATA/room/device-id
        :param service: full service name, in the format of /home/SERVICE/room/device-id
        :param is_cmd: whether to send a command to the service
        :param name_or_cmd: the command id (if is_command is true) or the content-id (if is_cmd is false)
        :param param: content payload or command parameters
        :return: a dict object containing the state
        """
        service_name = Name.from_str(service)
        service_id = service_name[1][2]
        logging.debug(f'Use service: {str(service_id)}')
        encryption_key = None
        for service_meta in self.service_list.service_meta_items:
            if service_meta.service_id == service_id:
                encryption_key = service_meta.encryption_key
        if is_cmd == 'true':
            logging.debug(
                F'******Command publish timestamp: {int(round(time.time() * 1000))}'
            )
            service_name.insert(2, 'CMD')
            service_name = service_name + Name.from_str(name_or_cmd)
            service_name.append(Component.from_timestamp(timestamp()))
            notification_name = service_name[:]
            notification_name.insert(2, 'NOTIFY')

            need_register = False
            need_unregister = False
            if self.newly_pub_command is None:
                need_register = True
            elif Name.to_str(self.newly_pub_command[:3]) != Name.to_str(
                    service_name[:3]):
                need_register = True
                need_unregister = True

            if need_unregister:
                success = await self.app.unregister(self.newly_pub_command[:3])
                if not success:
                    logging.debug(
                        'cannot unregister prefix for command publish')

            self.newly_pub_command = service_name
            self.newly_pub_payload = param.encode()
            logging.debug(f'New pub info: {param}')
            logging.debug('Encryption Key: ')
            logging.debug(bytes(encryption_key))
            logging.debug('Plaintext: ')
            logging.debug(self.newly_pub_payload)
            # AES encryption
            iv = urandom(16)
            cipher = AES.new(bytes(encryption_key), AES.MODE_CBC, iv)
            ct_bytes = cipher.encrypt(pad(self.newly_pub_payload, 16))
            content_tlv = CipherBlock()
            content_tlv.iv = iv
            content_tlv.cipher = ct_bytes
            self.newly_pub_payload = content_tlv.encode()

            logging.info(
                F'Publish new content Data packet {Name.to_str(self.newly_pub_command)}'
            )

            if need_register:

                def on_service_fetch(name: FormalName,
                                     int_param: InterestParam,
                                     app_param: Optional[BinaryStr]):
                    logging.debug(
                        'received Interest to fetch newly published command')
                    self.app.put_data(self.newly_pub_command,
                                      self.newly_pub_payload,
                                      freshness_period=3000,
                                      identity=self.system_prefix)
                    return

                success = await self.app.register(service_name[:3],
                                                  on_service_fetch)
                if not success:
                    logging.debug('cannot register prefix for command publish')

            coroutine = self.app.express_interest(notification_name,
                                                  must_be_fresh=True,
                                                  can_be_prefix=True,
                                                  identity=self.system_prefix)
            ret = {
                'name': Name.to_str(service_name),
                'response_type': 'CommandPublished'
            }
        else:
            service_name.insert(2, 'DATA')
            service_name = service_name + Name.from_str(name_or_cmd)
            time1 = time.time()
            ret = await self.express_interest(service_name, None, True, True,
                                              False)
            time2 = time.time()
            logging.debug(
                F'******Data Fetching Round Trip Time: {time2 - time1}s******')
            if ret['response_type'] == 'Data':
                content = ret['content']
                content = CipherBlock.parse(content)
                iv = bytes(content.iv)
                cipher = AES.new(bytes(encryption_key), AES.MODE_CBC, iv)
                payload = cipher.decrypt(bytes(content.cipher))

                time2 = time.time()
                logging.debug(
                    F'******Data Fetching Finish Time: {time2 - time1}s******')

                payload = unpad(payload, 16)
                ret['content'] = payload.decode()
        return ret