def get_private_key() -> bytes: app_path = click.get_app_dir("ledgerctl") if not os.path.exists(app_path): os.makedirs(app_path) cfg_file = os.path.join(app_path, "config.ini") try: config = configparser.RawConfigParser() config.read(cfg_file) default_config = config["DEFAULT"] private_key = bytes.fromhex(default_config["private_key"]) except KeyError: new_private_key = PrivateKey() public_key = new_private_key.pubkey pubkey_bytes = public_key.serialize(compressed=False) config = configparser.RawConfigParser() config["DEFAULT"] = { "public_key": pubkey_bytes.hex(), "private_key": new_private_key.serialize().hex(), } with click.open_file(cfg_file, "w") as f: config.write(f) private_key = bytes.fromhex(new_private_key.serialize().hex()) return private_key
def __init__(self, device, cla=0xE0, private_key=None): self.device = device self.cla = cla self._target_id = None self.scp = None if private_key is None: self.private_key = PrivateKey() else: self.private_key = PrivateKey(private_key) device.open()
def __init__(self, device=None, cla=0xE0, private_key=None): if device is None: devices = enumerate_devices() if len(devices) == 0: raise NoLedgerDeviceException("No Ledger device has been found.") device = devices[0] self.device = device self.cla = cla self._target_id = None self.scp = None if private_key is None: self.private_key = PrivateKey() else: self.private_key = PrivateKey(private_key) self.device.open()
def test_get_ecdh_secret(self, client): pubkey = PrivateKey().pubkey.serialize(compressed=False) payload = Bip32Path.build(DEFAULT_PATH) + pubkey client.apdu_exchange(self.INS, payload, sw1=P1.FIRST, sw2=Curve.PRIME256)
def receive_certificate_chain(self): cert_chain = [] if self.cert_chain is not None: cert_chain.append(self.cert_chain) else: data_to_sign = bytes([CERT_ROLE_SIGNER]) + self.master_public master_signature = self.master_private.sign(data_to_sign) cert_chain.append( serialize(self.master_public) + serialize(master_signature)) # Provide the ephemeral certificate, signed with the master public key self.ephemeral_private = PrivateKey() ephemeral_public = self.ephemeral_private.pubkey.serialize( compressed=False) # print("Using ephemeral key {}".format(ephemeral_public.hex())) data_to_sign = (bytes([CERT_ROLE_SIGNER_EPHEMERAL]) + self.server_nonce + self.device_nonce + ephemeral_public) signature = self.master_private.sign(data_to_sign) cert_chain.append(serialize(ephemeral_public) + serialize(signature)) return cert_chain
def install_ca(get_client, name, public_key): if public_key is None: raw_private_key = get_private_key() pubkey_bytes = PrivateKey(raw_private_key).pubkey.serialize(compressed=False) else: pubkey_bytes = bytes.fromhex(public_key) try: get_client().install_ca(name, pubkey_bytes) click.echo("Custom certificate has been successfully installed.") except CommException as e: if e.sw == 0x6982: click.echo("A certificate is already installed on the device.") elif e.sw == 0x6802: # INVALID_PARAMETER click.echo("The provided certificate is invalid.") else: raise
class SimpleServer(LedgerServer): def __init__(self, master_private: PrivateKey, cert_chain=None): self.device_nonce = None self.server_nonce = None self.master_private = master_private self.master_public = master_private.pubkey.serialize(False) self.shared_secret = None self.ephemeral_private = None self.cert_chain = cert_chain def receive_certificate_chain(self): cert_chain = [] if self.cert_chain is not None: cert_chain.append(self.cert_chain) else: data_to_sign = bytes([CERT_ROLE_SIGNER]) + self.master_public master_signature = self.master_private.sign(data_to_sign) cert_chain.append( serialize(self.master_public) + serialize(master_signature)) # Provide the ephemeral certificate, signed with the master public key self.ephemeral_private = PrivateKey() ephemeral_public = self.ephemeral_private.pubkey.serialize( compressed=False) # print("Using ephemeral key {}".format(ephemeral_public.hex())) data_to_sign = (bytes([CERT_ROLE_SIGNER_EPHEMERAL]) + self.server_nonce + self.device_nonce + ephemeral_public) signature = self.master_private.sign(data_to_sign) cert_chain.append(serialize(ephemeral_public) + serialize(signature)) return cert_chain def send_certicate_chain(self, chain): assert len(chain) == 2 last_dev_pub_key = PublicKey(self.master_public) for i, item in enumerate(chain): certificate_header, item = unserialize(item) certificate_public_key, item = unserialize(item) certificate_signature_array, _ = unserialize(item) certificate_signature = certificate_signature_array # first cert contains a header field which holds the certificate's public key role if i == 0: # device_public_key = certificate_public_key certificate_signed_data = (bytes([CERT_ROLE_DEVICE]) + certificate_header + certificate_public_key) # Could check if the device certificate is signed by the issuer public key # ephemeral key certificate else: certificate_signed_data = ( bytes([CERT_ROLE_DEVICE_EPHEMERAL]) + self.device_nonce + self.server_nonce + certificate_public_key) if not last_dev_pub_key.verify(certificate_signed_data, certificate_signature): """ if index == 0: # Not an error if loading from user key print("Broken certificate chain - loading from user key") else: raise Exception("Broken certificate chain") """ if i != 0: raise Exception("Broken certificate chain") last_dev_pub_key = PublicKey(certificate_public_key) self.shared_secret = self.ephemeral_private.exchange(last_dev_pub_key) def get_nonce(self) -> bytes: self.server_nonce = os.urandom(8) return self.server_nonce def send_nonce(self, nonce: bytes): assert len(nonce) == 8 self.device_nonce = nonce def get_shared_secret(self): return self.shared_secret