def bootstrap(): global trust_anchor, signer import_safebag("sec/server.safebag", "1234") import_cert("sec/server.ndncert") with open("sec/server.safebag", "r") as safebag: wire = safebag.read() wire = base64.b64decode(wire) wire = parse_and_check_tl(wire, SecurityV2TypeNumber.SAFE_BAG) bag = SafeBag.parse(wire) testbed_signed = CertificateV2Value.parse(bag.certificate_v2) server_key_name = Name.to_str(testbed_signed.name[:-2]) privateKey = serialization.load_der_private_key( bytes(bag.encrypted_key_bag), password=b'1234', backend=default_backend()) server_prv_key = privateKey.private_bytes(Encoding.DER, PrivateFormat.PKCS8, NoEncryption()) signer = Sha256WithEcdsaSigner(server_key_name, server_prv_key) with open("sec/testbed.anchor", "r") as ndncert: wire = ndncert.read() wire = base64.b64decode(wire) trust_anchor = parse_certificate(wire)
def get_prv_key_from_safe_bag(id_name): """ Export the safebag with password 1234 using ndnsec-export command line tool. The function then parse the exported safe bag and return the private key bytes. :param id_name: the NDN identity name """ p = subprocess.run(['ndnsec-export', id_name, '-P', '1234'], stdout=subprocess.PIPE) wire = base64.b64decode(p.stdout) logging.debug('result from ndnsec-export') logging.debug(wire) wire = parse_and_check_tl(wire, SecurityV2TypeNumber.SAFE_BAG) bag = SafeBag.parse(wire) # Don't use unwrap because the key returned is still in DER format #key = unwrap(bytes(bag.encrypted_key_bag), '1234')[1] privateKey = serialization.load_der_private_key(bytes( bag.encrypted_key_bag), password=b'1234', backend=default_backend()) ecc_key = ECC.import_key( privateKey.private_bytes(Encoding.DER, PrivateFormat.PKCS8, NoEncryption())) logging.debug("pub key: ") logging.debug(ecc_key.pointQ.xy) logging.debug("prv key: ") logging.debug(ecc_key.d) cert_prv_key = ecc_key.d.to_bytes() logging.info("Private KEY: ") logging.info(cert_prv_key) return cert_prv_key
def get_prv_key_from_safe_bag(id_name): p = subprocess.run(['ndnsec-export', id_name, '-P', '1234'], stdout=subprocess.PIPE) wire = base64.b64decode(p.stdout) wire = parse_and_check_tl(wire, SecurityV2TypeNumber.SAFE_BAG) bag = SafeBag.parse(wire) algo, key, param = unwrap(bytes(bag.encrypted_key_bag), '1234') return key
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()