def generate_ec_key(self, key_slot, curve_name, timestamp=None): """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.unwrap(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 is_pkcs12(data): """ Tries to identify a PKCS12 container. The PFX PDU version is assumed to be v3. See: https://tools.ietf.org/html/rfc7292. """ try: header = Tlv.parse_list(Tlv.unwrap(0x30, data))[0] return header.tag == 0x02 and header.value == b"\x03" except ValueError: return False
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())