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()
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
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)
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()
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
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`'
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()
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