def generate_ec_key(self, key_slot, curve_name, timestamp=None): require_version(self.version, (5, 2, 0)) """Requires Admin PIN verification.""" if timestamp is None: timestamp = int(time.time()) attributes = _format_ec_attributes(key_slot, curve_name) self._put_data(key_slot.key_id, attributes) resp = self._app.send_apdu(0, INS.GENERATE_ASYM, 0x80, 0x00, key_slot.crt) data = Tlv.parse_dict(Tlv.unpack(0x7F49, resp)) pubkey_enc = data[0x86] self._put_data(key_slot.gen_time, struct.pack(">I", timestamp)) # TODO: Calculate and write fingerprint if curve_name == "x25519": # Added in 2.0 from cryptography.hazmat.primitives.asymmetric import x25519 return x25519.X25519PublicKey.from_public_bytes(pubkey_enc) if curve_name == "ed25519": # Added in 2.6 from cryptography.hazmat.primitives.asymmetric import ed25519 return ed25519.Ed25519PublicKey.from_public_bytes(pubkey_enc) curve = getattr(ec, curve_name.upper()) try: # Added in cryptography 2.5 return ec.EllipticCurvePublicKey.from_encoded_point(curve(), pubkey_enc) except AttributeError: return ec.EllipticCurvePublicNumbers.from_encoded_point( curve(), pubkey_enc ).public_key(default_backend())
def test_read_write_certificate_as_object(self): with self.assertRaises(SystemExit): ykman_cli("piv", "read-object", hex(OBJECT_ID.AUTHENTICATION)) cert = generate_self_signed_certificate() cert_bytes_der = cert.public_bytes( encoding=serialization.Encoding.DER) input_tlv = Tlv(0x70, cert_bytes_der) + Tlv(0x71, b"\0") + Tlv( 0xFE, b"") ykman_cli( "piv", "write-object", hex(OBJECT_ID.AUTHENTICATION), "-", "-m", DEFAULT_MANAGEMENT_KEY, input=input_tlv, ) output1 = ykman_cli.with_bytes_output( "piv", "read-object", hex(OBJECT_ID.AUTHENTICATION)) output_cert_bytes = Tlv.parse_dict(output1)[0x70] self.assertEqual(output_cert_bytes, cert_bytes_der) output2 = ykman_cli.with_bytes_output( "piv", "export-certificate", hex(SLOT.AUTHENTICATION), "-", "--format", "DER", ) self.assertEqual(output2, cert_bytes_der)
def __init__(self, raw_data: bytes = Tlv(0x80)): data = Tlv.parse_dict(Tlv(raw_data).value) self._flags = struct.unpack(">B", data[0x81])[0] if 0x81 in data else None self.salt = data.get(0x82) self.pin_timestamp = struct.unpack( ">I", data[0x83]) if 0x83 in data else None
def generate_rsa_key(self, key_slot, key_size, timestamp=None): """Requires Admin PIN verification.""" if (4, 2, 0) <= self.version < (4, 3, 5): raise NotSupportedError( "RSA key generation not supported on this YubiKey") if timestamp is None: timestamp = int(time.time()) neo = self.version < (4, 0, 0) if not neo: attributes = _format_rsa_attributes(key_size) self._put_data(key_slot.key_id, attributes) elif key_size != 2048: raise ValueError("Unsupported key size!") resp = self._app.send_apdu(0, INS.GENERATE_ASYM, 0x80, 0x00, key_slot.crt) data = Tlv.parse_dict(Tlv.unpack(0x7F49, resp)) numbers = rsa.RSAPublicNumbers(bytes2int(data[0x82]), bytes2int(data[0x81])) self._put_data(key_slot.gen_time, struct.pack(">I", timestamp)) # TODO: Calculate and write fingerprint return numbers.public_key(default_backend())
def parse(cls, data: bytes) -> "KdfData": fields = Tlv.parse_dict(data) return cls( _parse_int(fields, 0x81, KdfAlgorithm, KdfAlgorithm.NONE), _parse_int(fields, 0x82, HashAlgorithm), _parse_int(fields, 0x83), fields.get(0x84), fields.get(0x85), fields.get(0x86), fields.get(0x87), fields.get(0x88), )
def test_read_write_certificate_as_object(self, ykman_cli): with pytest.raises(SystemExit): ykman_cli("piv", "objects", "export", hex(OBJECT_ID.AUTHENTICATION), "-") cert = generate_self_signed_certificate() cert_bytes_der = cert.public_bytes(encoding=serialization.Encoding.DER) input_tlv = Tlv(0x70, cert_bytes_der) + Tlv(0x71, b"\0") + Tlv( 0xFE, b"") ykman_cli( "piv", "objects", "import", hex(OBJECT_ID.AUTHENTICATION), "-", "-m", DEFAULT_MANAGEMENT_KEY, input=input_tlv, ) output1 = ykman_cli("piv", "objects", "export", hex(OBJECT_ID.AUTHENTICATION), "-").stdout_bytes output_cert_bytes = Tlv.parse_dict(output1)[0x70] assert output_cert_bytes == cert_bytes_der output2 = ykman_cli( "piv", "certificates", "export", hex(SLOT.AUTHENTICATION), "-", "--format", "DER", ).stdout_bytes assert output2 == cert_bytes_der
def generate_rsa_key(self, key_slot, key_size, timestamp=None): """Requires Admin PIN verification.""" ensure_not_cve201715361_vulnerable_firmware_version(self.version) if timestamp is None: timestamp = int(time.time()) neo = self.version < (4, 0, 0) if not neo: attributes = _format_rsa_attributes(key_size) self._put_data(key_slot.key_id, attributes) elif key_size != 2048: raise ValueError("Unsupported key size!") resp = self._app.send_apdu(0, INS.GENERATE_ASYM, 0x80, 0x00, key_slot.crt) data = Tlv.parse_dict(Tlv.unwrap(0x7F49, resp)) numbers = rsa.RSAPublicNumbers( int_from_bytes(data[0x82], "big"), int_from_bytes(data[0x81], "big") ) self._put_data(key_slot.gen_time, struct.pack(">I", timestamp)) # TODO: Calculate and write fingerprint return numbers.public_key(default_backend())
def __init__(self, raw_data: bytes = Tlv(0x88)): data = Tlv.parse_dict(Tlv(raw_data).value) self.key = data.get(0x89)