<commit_before># key.py - module for handling keys from pskc files
# coding: utf-8
#
# Copyright (C) 2014-2015 <NAME>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA

"""Module that handles keys stored in PSKC files."""


import base64

from pskc.encryption import EncryptedValue
from pskc.mac import ValueMAC
from pskc.policy import Policy


class DataType(object):
    """Provide access to possibly encrypted, MAC'ed information.

    This class is meant to be subclassed to provide typed access to stored
    values. Instances of this class provide the following attributes:

      value: unencrypted value if present
      encrypted_value: reference to an EncryptedValue instance
      value_mac: reference to a ValueMAC instance
    """

    def __init__(self, key, element=None):
        self.value = None
        self.encrypted_value = EncryptedValue(key.pskc.encryption)
        self.value_mac = ValueMAC(key.pskc.mac)
        self.parse(element)

    def parse(self, element):
        """Read information from the provided element.

        The element is expected to contain <PlainValue>, <EncryptedValue>
        and/or ValueMAC elements that contain information on the actual
        value."""
        from pskc.xml import find, findtext
        if element is None:
            return
        value = findtext(element, 'pskc:PlainValue')
        if value is not None:
            self.value = self.from_text(value)
        self.encrypted_value.parse(find(element, 'pskc:EncryptedValue'))
        self.value_mac.parse(find(element, 'pskc:ValueMAC'))

    def from_text(self, value):
        """Convert the plain value to native representation."""
        raise NotImplementedError

    def to_text(self, value):
        """Convert the value to an unencrypted string representation."""
        raise NotImplementedError

    def from_bin(self, value):
        """Convert the unencrypted binary to native representation."""
        return value

    def make_xml(self, key, tag):
        from pskc.xml import find, mk_elem
        # skip empty values
        value = self.get_value()
        if value is None:
            return
        # find the data tag and create our tag under it
        data = find(key, 'pskc:Data')
        if data is None:
            data = mk_elem(key, 'pskc:Data', empty=True)
        element = mk_elem(data, tag, empty=True)
        mk_elem(element, 'pskc:PlainValue', self.to_text(self.value))

    def get_value(self):
        """Provide the raw binary value."""
        if self.value is not None:
            return self.value
        if self.encrypted_value.cipher_value:
            # check MAC and decrypt
            self.check()
            return self.from_bin(self.encrypted_value.decrypt())

    def set_value(self, value):
        """Set the unencrypted value."""
        self.value = value
        self.encrypted_value.cipher_value = None

    def check(self):
        """Check whether the embedded MAC is correct."""
        # this checks the encrypted value
        return self.value_mac.check(self.encrypted_value.cipher_value)


class BinaryDataType(DataType):
    """Subclass of DataType for binary data (e.g. keys)."""

    def from_text(self, value):
        """Convert the plain value to native representation."""
        return base64.b64decode(value)

    def to_text(self, value):
        """Convert the value to an unencrypted string representation."""
        # force conversion to bytestring on Python 3
        if not isinstance(value, type(b'')):
            value = value.encode()
        return base64.b64encode(value).decode()


class IntegerDataType(DataType):
    """Subclass of DataType for integer types (e.g. counters)."""

    def from_text(self, value):
        """Convert the plain value to native representation."""
        return int(value)

    def to_text(self, value):
        """Convert the value to an unencrypted string representation."""
        return str(value)

    def from_bin(self, value):
        """Convert the unencrypted binary to native representation."""
        result = 0
        for x in value:
            result = (result << 8) + ord(x)
        return result


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<commit_msg>Make value conversion methods static private<commit_after># key.py - module for handling keys from pskc files
# coding: utf-8
#
# Copyright (C) 2014-2015 <NAME>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA

"""Module that handles keys stored in PSKC files."""


import base64

from pskc.encryption import EncryptedValue
from pskc.mac import ValueMAC
from pskc.policy import Policy


class DataType(object):
    """Provide access to possibly encrypted, MAC'ed information.

    This class is meant to be subclassed to provide typed access to stored
    values. Instances of this class provide the following attributes:

      value: unencrypted value if present
      encrypted_value: reference to an EncryptedValue instance
      value_mac: reference to a ValueMAC instance
    """

    def __init__(self, key, element=None):
        self.value = None
        self.encrypted_value = EncryptedValue(key.pskc.encryption)
        self.value_mac = ValueMAC(key.pskc.mac)
        self.parse(element)

    def parse(self, element):
        """Read information from the provided element.

        The element is expected to contain <PlainValue>, <EncryptedValue>
        and/or ValueMAC elements that contain information on the actual
        value."""
        from pskc.xml import find, findtext
        if element is None:
            return
        value = findtext(element, 'pskc:PlainValue')
        if value is not None:

            self.value = self._from_text(value)
        self.encrypted_value.parse(find(element, 'pskc:EncryptedValue'))
        self.value_mac.parse(find(element, 'pskc:ValueMAC'))

    @staticmethod
    def _from_text(value):
        """Convert the plain value to native representation."""
        raise NotImplementedError

    @staticmethod
    def _to_text(value):
        """Convert the value to an unencrypted string representation."""
        raise NotImplementedError

    @staticmethod
    def _from_bin(value):
        """Convert the unencrypted binary to native representation."""
        return value

    def make_xml(self, key, tag):
        from pskc.xml import find, mk_elem
        # skip empty values
        value = self.get_value()
        if value is None:
            return
        # find the data tag and create our tag under it
        data = find(key, 'pskc:Data')
        if data is None:
            data = mk_elem(key, 'pskc:Data', empty=True)
        element = mk_elem(data, tag, empty=True)
        mk_elem(element, 'pskc:PlainValue', self._to_text(self.value))

    def get_value(self):
        """Provide the raw binary value."""
        if self.value is not None:
            return self.value
        if self.encrypted_value.cipher_value:
            # check MAC and decrypt
            self.check()
            return self._from_bin(self.encrypted_value.decrypt())

    def set_value(self, value):
        """Set the unencrypted value."""
        self.value = value
        self.encrypted_value.cipher_value = None

    def check(self):
        """Check whether the embedded MAC is correct."""
        # this checks the encrypted value
        return self.value_mac.check(self.encrypted_value.cipher_value)


class BinaryDataType(DataType):
    """Subclass of DataType for binary data (e.g. keys)."""

    @staticmethod
    def _from_text(value):
        """Convert the plain value to native representation."""
        return base64.b64decode(value)

    @staticmethod
    def _to_text(value):
        """Convert the value to an unencrypted string representation."""
        # force conversion to bytestring on Python 3
        if not isinstance(value, type(b'')):
            value = value.encode()
        return base64.b64encode(value).decode()


class IntegerDataType(DataType):
    """Subclass of DataType for integer types (e.g. counters)."""

    @staticmethod
    def _from_text(value):
        """Convert the plain value to native representation."""
        return int(value)

    @staticmethod
    def _to_text(value):
        """Convert the value to an unencrypted string representation."""
        return str(value)

    @staticmethod
    def _from_bin(value):
        """Convert the unencrypted binary to native representation."""
        result = 0
        for x in value:
            result = (result << 8) + ord(x)
        return result


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
{'fraction_non_alphanumeric': 0.07835982972808618, 'fraction_numerical': 0.0060811397793414995, 'mean_word_length': 2.8747896331201614, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 6}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5340876', 'n_tokens_mistral': 3085, 'n_tokens_neox': 2969, 'n_words': 1214}