def __init__(self, device): self.device = device self.id = None self.algorithm = None self._secret = BinaryDataType(self.device.pskc) self._counter = IntegerDataType(self.device.pskc) self._time_offset = IntegerDataType(self.device.pskc) self._time_interval = IntegerDataType(self.device.pskc) self._time_drift = IntegerDataType(self.device.pskc) self.issuer = None self.key_profile = None self.key_reference = None self.friendly_name = None self.key_userid = None self.algorithm_suite = None self.challenge_encoding = None self.challenge_min_length = None self.challenge_max_length = None self.challenge_check = None self.response_encoding = None self.response_length = None self.response_check = None self.policy = Policy(self)
def __init__(self, device): self.device = device self.id = None self.algorithm = None self.issuer = None self.key_profile = None self.key_reference = None self.friendly_name = None self.key_userid = None self.algorithm_suite = None self.challenge_encoding = None self.challenge_min_length = None self.challenge_max_length = None self.challenge_check = None self.response_encoding = None self.response_length = None self.response_check = None self.policy = Policy(self)
def __init__(self, pskc, key_package=None): self.pskc = pskc self.id = None self.algorithm = None self._secret = BinaryDataType(self) self._counter = IntegerDataType(self) self._time_offset = IntegerDataType(self) self._time_interval = IntegerDataType(self) self._time_drift = IntegerDataType(self) self.issuer = None self.key_profile = None self.key_reference = None self.friendly_name = None self.key_userid = None self.manufacturer = None self.serial = None self.model = None self.issue_no = None self.device_binding = None self.start_date = None self.expiry_date = None self.device_userid = None self.crypto_module = None self.algorithm_suite = None self.challenge_encoding = None self.challenge_min_length = None self.challenge_max_length = None self.challenge_check = None self.response_encoding = None self.response_length = None self.response_check = None self.policy = Policy(self) self.parse(key_package)
class Key(object): """Representation of a single key from a PSKC file. Instances of this class provide the following properties: id: unique key identifier (should be constant between interchanges) algorithm: identifier of the PSKC algorithm profile (URI) secret: the secret key itself (binary form, automatically decrypted) counter: event counter for event-based OTP time_offset: time offset for time-based OTP algorithms (in intervals) time_interval: time interval for time-based OTP in seconds time_drift: device clock drift (negative means device is slow) issuer: party that issued the key key_profile: reference to pre-shared key profile information key_reference: reference to an external key friendly_name: human-readable name for the secret key key_userid: user distinguished name associated with the key manufacturer: name of the organisation that made the device serial: serial number of the device model: device model description issue_no: issue number per serial number device_binding: device (class) identifier for the key to be loaded upon start_date: key should not be used before this date expiry_date: key or device may expire after this date device_userid: user distinguished name associated with the device crypto_module: id of module to which keys are provisioned within device algorithm_suite: additional algorithm characteristics (e.g. used hash) challenge_encoding: format of the challenge for CR devices challenge_min_length: minimum accepted challenge length by device challenge_max_length: maximum size challenge accepted by the device challenge_check: whether the device will check an embedded check digit response_encoding: format of the response the device will generate response_length: the length of the response of the device response_check: whether the device appends a Luhn check digit policy: reference to policy information (see Policy class) """ def __init__(self, pskc, key_package=None): self.pskc = pskc self.id = None self.algorithm = None self._secret = BinaryDataType(self) self._counter = IntegerDataType(self) self._time_offset = IntegerDataType(self) self._time_interval = IntegerDataType(self) self._time_drift = IntegerDataType(self) self.issuer = None self.key_profile = None self.key_reference = None self.friendly_name = None self.key_userid = None self.manufacturer = None self.serial = None self.model = None self.issue_no = None self.device_binding = None self.start_date = None self.expiry_date = None self.device_userid = None self.crypto_module = None self.algorithm_suite = None self.challenge_encoding = None self.challenge_min_length = None self.challenge_max_length = None self.challenge_check = None self.response_encoding = None self.response_length = None self.response_check = None self.policy = Policy(self) self.parse(key_package) def parse(self, key_package): """Read key information from the provided <KeyPackage> tree.""" from pskc.xml import find, findtext, findtime, getint, getbool if key_package is None: return key = find(key_package, "pskc:Key") if key is not None: self.id = key.get("Id") self.algorithm = key.get("Algorithm") data = find(key_package, "pskc:Key/pskc:Data") if data is not None: self._secret.parse(find(data, "pskc:Secret")) self._counter.parse(find(data, "pskc:Counter")) self._time_offset.parse(find(data, "pskc:Time")) self._time_interval.parse(find(data, "pskc:TimeInterval")) self._time_drift.parse(find(data, "pskc:TimeDrift")) self.issuer = findtext(key_package, "pskc:Key/pskc:Issuer") self.key_profile = findtext(key_package, "pskc:Key/pskc:KeyProfileId") self.key_reference = findtext(key_package, "pskc:Key/pskc:KeyReference") self.friendly_name = findtext(key_package, "pskc:Key/pskc:FriendlyName") # TODO: support multi-language values of <FriendlyName> self.key_userid = findtext(key_package, "pskc:Key/pskc:UserId") self.manufacturer = findtext(key_package, "pskc:DeviceInfo/pskc:Manufacturer") self.serial = findtext(key_package, "pskc:DeviceInfo/pskc:SerialNo") self.model = findtext(key_package, "pskc:DeviceInfo/pskc:Model") self.issue_no = findtext(key_package, "pskc:DeviceInfo/pskc:IssueNo") self.device_binding = findtext(key_package, "pskc:DeviceInfo/pskc:DeviceBinding") self.start_date = findtime(key_package, "pskc:DeviceInfo/pskc:StartDate") self.expiry_date = findtime(key_package, "pskc:DeviceInfo/pskc:ExpiryDate") self.device_userid = findtext(key_package, "pskc:DeviceInfo/pskc:UserId") self.crypto_module = findtext(key_package, "pskc:CryptoModuleInfo/pskc:Id") self.algorithm_suite = findtext(key_package, "pskc:Key/pskc:AlgorithmParameters/pskc:Suite") challenge_format = find(key_package, "pskc:Key/pskc:AlgorithmParameters/pskc:ChallengeFormat") if challenge_format is not None: self.challenge_encoding = challenge_format.get("Encoding") self.challenge_min_length = getint(challenge_format, "Min") self.challenge_max_length = getint(challenge_format, "Max") self.challenge_check = getbool(challenge_format, "CheckDigits") response_format = find(key_package, "pskc:Key/pskc:AlgorithmParameters/pskc:ResponseFormat") if response_format is not None: self.response_encoding = response_format.get("Encoding") self.response_length = getint(response_format, "Length") self.response_check = getbool(response_format, "CheckDigits") self.policy.parse(find(key_package, "pskc:Key/pskc:Policy")) def make_xml(self, container): from pskc.xml import mk_elem key_package = mk_elem(container, "pskc:KeyPackage", empty=True) if any( x is not None for x in ( self.manufacturer, self.serial, self.model, self.issue_no, self.device_binding, self.start_date, self.expiry_date, self.device_userid, ) ): device_info = mk_elem(key_package, "pskc:DeviceInfo", empty=True) mk_elem(device_info, "pskc:Manufacturer", self.manufacturer) mk_elem(device_info, "pskc:SerialNo", self.serial) mk_elem(device_info, "pskc:Model", self.model) mk_elem(device_info, "pskc:IssueNo", self.issue_no) mk_elem(device_info, "pskc:DeviceBinding", self.device_binding) mk_elem(device_info, "pskc:StartDate", self.start_date) mk_elem(device_info, "pskc:ExpiryDate", self.expiry_date) mk_elem(device_info, "pskc:UserId", self.device_userid) if self.crypto_module is not None: crypto_module = mk_elem(key_package, "pskc:CryptoModuleInfo", empty=True) mk_elem(crypto_module, "pskc:Id", self.crypto_module) key = mk_elem(key_package, "pskc:Key", empty=True, Id=self.id, Algorithm=self.algorithm) mk_elem(key, "pskc:Issuer", self.issuer) if any((self.algorithm_suite, self.challenge_encoding, self.response_encoding, self.response_length)): parameters = mk_elem(key, "pskc:AlgorithmParameters", empty=True) mk_elem(parameters, "pskc:Suite", self.algorithm_suite) mk_elem( parameters, "pskc:ChallengeFormat", Encoding=self.challenge_encoding, Min=self.challenge_min_length, Max=self.challenge_max_length, CheckDigits=self.challenge_check, ) mk_elem( parameters, "pskc:ResponseFormat", Encoding=self.response_encoding, Length=self.response_length, CheckDigits=self.response_check, ) mk_elem(key, "pskc:KeyProfileId", self.key_profile) mk_elem(key, "pskc:KeyReference", self.key_reference) mk_elem(key, "pskc:FriendlyName", self.friendly_name) self._secret.make_xml(key, "pskc:Secret") self._counter.make_xml(key, "pskc:Counter") self._time_offset.make_xml(key, "pskc:Time") self._time_interval.make_xml(key, "pskc:TimeInterval") self._time_drift.make_xml(key, "pskc:TimeDrift") mk_elem(key, "pskc:UserId", self.key_userid) self.policy.make_xml(key) secret = property( fget=lambda self: self._secret.get_value(), fset=lambda self, x: self._secret.set_value(x), doc="The secret key itself.", ) counter = property( fget=lambda self: self._counter.get_value(), fset=lambda self, x: self._counter.set_value(x), doc="An event counter for event-based OTP.", ) time_offset = property( fget=lambda self: self._time_offset.get_value(), fset=lambda self, x: self._time_offset.set_value(x), doc="A time offset for time-based OTP (number of intervals).", ) time_interval = property( fget=lambda self: self._time_interval.get_value(), fset=lambda self, x: self._time_interval.set_value(x), doc="A time interval in seconds.", ) time_drift = property( fget=lambda self: self._time_drift.get_value(), fset=lambda self, x: self._time_drift.set_value(x), doc="Device clock drift value (number of time intervals).", ) def check(self): """Check if all MACs in the message are valid.""" if any( ( self._secret.check(), self._counter.check(), self._time_offset.check(), self._time_interval.check(), self._time_drift.check(), ) ): return True