From cf0c9e618a160c645879ae66fe6cb1bdec5e47a3 Mon Sep 17 00:00:00 2001 From: Arthur de Jong Date: Wed, 7 Oct 2015 19:57:13 +0200 Subject: Update documentation This updates the documentation with the new features (writing PSKC files) as well as many editorial improvements, some rewording and a few typo fixes. Some things were moved around a little in order to be more easily readable and easier to find. --- docs/conf.py | 2 +- docs/encryption.rst | 12 +++-- docs/exceptions.rst | 6 +-- docs/mac.rst | 28 ++++++---- docs/policy.rst | 27 +++++++--- docs/usage.rst | 151 ++++++++++++++++++++++++++++++++++------------------ 6 files changed, 146 insertions(+), 80 deletions(-) (limited to 'docs') diff --git a/docs/conf.py b/docs/conf.py index 0ab5e14..268d158 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -46,7 +46,7 @@ master_doc = 'index' # General information about the project. project = u'python-pskc' -copyright = u'2014, Arthur de Jong' +copyright = u'2014-2015 Arthur de Jong' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the diff --git a/docs/encryption.rst b/docs/encryption.rst index e0c8ca0..8b0ed2f 100644 --- a/docs/encryption.rst +++ b/docs/encryption.rst @@ -8,26 +8,30 @@ pre-shared keys, passphrase-based keys or asymmetric keys (asymmetric keys are currently unimplemented). Embedded PSKC encryption is handled inside the :class:`Encryption` class that -defines encryption key and means of deriving keys. It is accessed from the +defines encryption key or means of deriving keys. It is accessed from the :attr:`~pskc.PSKC.encryption` attribute of a :class:`~pskc.PSKC` instance:: + >>> rom binascii import a2b_hex >>> from pskc import PSKC >>> pskc = PSKC('somefile.pskcxml') - >>> pskc.encryption.key = '12345678901234567890123456789012'.decode('hex') + >>> pskc.encryption.key = a2b_hex('12345678901234567890123456789012') or:: >>> pskc.encryption.derive_key('qwerty') -Once the encryption key has been set up any encrypted key values from the +Once the encryption key has been set up, any encrypted key values from the PSKC file are available transparently. -If an incorrect key has been set up, only upon accessing encrypted +If an incorrect key has been set up, upon accessing encrypted information (e.g. the :attr:`~pskc.key.Key.secret` attribute of a :class:`~pskc.key.Key` instance) a :exc:`~pskc.exceptions.DecryptionError` exception will be raised. +The Encryption class +-------------------- + .. class:: Encryption .. attribute:: id diff --git a/docs/exceptions.rst b/docs/exceptions.rst index bf1414f..fbd8e7f 100644 --- a/docs/exceptions.rst +++ b/docs/exceptions.rst @@ -22,9 +22,9 @@ Exceptions .. exception:: DecryptionError - Raised when decrypting the embedded encrypted value fails due to missing - or incorrect key, unsupported decryption or MAC algorithm, failed message - authentication check or other error. + Raised when decrypting a value fails due to missing or incorrect key, + unsupported decryption or MAC algorithm, failed message authentication + check or other error. This exception is generally raised when accessing encrypted information (i.e. the :attr:`~pskc.key.Key.secret`, :attr:`~pskc.key.Key.counter`, diff --git a/docs/mac.rst b/docs/mac.rst index 6e50626..4847071 100644 --- a/docs/mac.rst +++ b/docs/mac.rst @@ -7,6 +7,23 @@ The PSKC format allows for `message authentication and integrity checking `_ for some of the values stored within the PSKC file. +Integrity checking is done transparently when accessing attributes that +are encrypted and contain a ValueMAC. + +Once the PSKC encryption key has been set up, key values can be explicitly +checked using the :func:`~pskc.key.Key.check` method:: + + >>> pskc = PSKC('somefile.pskcxml') + >>> pskc.encryption.derive_key('qwerty') + >>> pskc.mac.algorithm + 'http://www.w3.org/2000/09/xmldsig#hmac-sha1' + >>> all(key.check() for key in pskc.keys) + True + + +The MAC class +------------- + .. class:: MAC .. attribute:: algorithm @@ -21,14 +38,3 @@ stored within the PSKC file. MAC key is generated specifically for each PSKC file and encrypted with the PSKC encryption key, so the PSKC file should be decrypted first (see :doc:`encryption`). - - -Once the PSKC encryption key has been set up key values can be explicitly -checked using the :func:`~pskc.key.Key.check` method:: - - >>> pskc = PSKC('somefile.pskcxml') - >>> pskc.encryption.derive_key('qwerty') - >>> pskc.mac.algorithm - 'http://www.w3.org/2000/09/xmldsig#hmac-sha1' - >>> all(key.check() for key in pskc.keys) - True diff --git a/docs/policy.rst b/docs/policy.rst index 91c51e2..97f9250 100644 --- a/docs/policy.rst +++ b/docs/policy.rst @@ -3,7 +3,8 @@ Key usage policy .. module:: pskc.policy -The PSKC format allows for specifying `key and pin usage policy `__. +The PSKC format allows for specifying `key and pin usage policy `__ +per key. Instances of the :class:`Policy` class provide attributes that describe limits that are placed on key usage and requirements for key PIN protection:: @@ -13,6 +14,9 @@ limits that are placed on key usage and requirements for key PIN protection:: True +The Policy class +---------------- + .. class:: Policy .. attribute:: start_date @@ -38,13 +42,12 @@ limits that are placed on key usage and requirements for key PIN protection:: A list of `valid usage scenarios `__ for the key that the recipient should check against the intended usage of the - key. Also see :func:`may_use` and :ref:`the list of key usage constants - below `. + key. Also see :func:`may_use` and :ref:`key-use-constants` below. .. attribute:: pin_key_id - The unique `id` value used to reference the key within the PSKC file - that contains the value of the PIN that protects this key. + The unique `id` of the key within the PSKC file that contains the value + of the PIN that protects this key. .. attribute:: pin_key @@ -58,8 +61,8 @@ limits that are placed on key usage and requirements for key PIN protection:: .. attribute:: pin_usage - Describe how the PIN is used during the usage of the key. See :ref:`the - list of pin usage constants below `. + Describe how the PIN is used during the usage of the key. See + :ref:`pin-use-constants` below. .. attribute:: pin_max_failed_attemtps @@ -92,10 +95,14 @@ limits that are placed on key usage and requirements for key PIN protection:: .. function:: may_use(usage) Check whether the key may be used for the provided purpose. See - :ref:`the list of key usage constants below `. + :ref:`key-use-constants` below. + .. _key-use-constants: +Key usage constants +------------------- + The :class:`Policy` class provides the following key use constants (see :attr:`~Policy.key_usage` and :func:`~Policy.may_use`): @@ -149,8 +156,12 @@ The :class:`Policy` class provides the following key use constants (see The key is used to generate a new key based on a random number and the previous value of the key. + .. _pin-use-constants: +Pin usage constants +------------------- + The following constants for PIN use are defined in the :class:`Policy` class (see :attr:`~Policy.pin_usage`): diff --git a/docs/usage.rst b/docs/usage.rst index acbd60e..7a9cdcb 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -10,25 +10,74 @@ contain most of the useful information from the PSKC file. Opening a PSKC file ------------------- -.. module:: pskc - -Importing data from a PSKC file can be done by instantiating a -:class:`~pskc.PSKC` class:: +Importing data from a PSKC file can be done by instantiating the +:class:`~pskc.PSKC` class with a file name argument:: >>> from pskc import PSKC >>> pskc = PSKC('somefile.pskcxml') >>> pskc.version '1.0' +The :attr:`~pskc.PSKC.keys` attribute contains a list of keys in the PSKC +file. :class:`~pskc.key.Key` instances have a number of attributes that +provide information on the transmitted keys:: + + >>> key = pskc.keys[0] + >>> key.id + 'some-id' + >>> key.algorithm + 'urn:ietf:params:xml:ns:keyprov:pskc:hotp' + >>> key.secret + 'SOME_SECRET_VALUE' + +Attribute values will be ``None`` if it the value is not present in the PSKC +file. + +The :attr:`~pskc.key.Key.secret`, :attr:`~pskc.key.Key.counter`, +:attr:`~pskc.key.Key.time_offset`, :attr:`~pskc.key.Key.time_interval` or +:attr:`~pskc.key.Key.time_drift` attributes may be stored in encrypted form +in the PSKC file. Decryption of these properties is done when they are +accessed. If decryption is unsuccessful a +:exc:`~pskc.exceptions.DecryptionError` exception is raised. See +:doc:`encryption` for more information. + + +Writing a PSKC file +------------------- + +Creating a PSKC file can be done by creating a :class:`~pskc.PSKC` instance, +adding keys with :func:`~pskc.PSKC.add_key()` and writing the result:: + + >>> from pskc import PSKC + >>> pskc = PSKC() + >>> key = pskc.add_key(id='456', manufacturer='Manufacturer') + >>> key.id + '456' + >>> key.secret = '987654321' + >>> key.algorithm = 'urn:ietf:params:xml:ns:keyprov:pskc:hotp' + >>> pskc.write('output.pskcxml') + +Writing the data in encrypted form in the PSKC file is not yet supported so +currently opening an encrypted PSKC file, providing the encryption key and +writing the file should result in the same file but with encryption removed. + + +The PSKC class +-------------- + +.. module:: pskc .. class:: PSKC([filename]) The :class:`PSKC` class is used as a wrapper to access information from a PSKC file. - The whole file is parsed in one go. Instances of this class provide the - following attributes: If parsing the PSKC file fails, a - :exc:`~pskc.exceptions.ParseError` exception is raised. + The `filename` argument can be either the name of a file or a file-like + object. The whole file is parsed in one go. If parsing the PSKC file + fails, a :exc:`~pskc.exceptions.ParseError` exception is raised. + If no argument is provided, an instance without any keys is created. + + Instances of this class provide the following attributes and functions: .. attribute:: version @@ -49,42 +98,35 @@ Importing data from a PSKC file can be done by instantiating a .. attribute:: encryption :class:`~pskc.encryption.Encryption` instance that handles PSKC file - encryption. + encryption. See :doc:`encryption` for more information. .. attribute:: mac - :class:`~pskc.mac.MAC` instance that handles integrity checking. + :class:`~pskc.mac.MAC` instance for handling integrity checking. + See :doc:`mac` for more information. -Examining keys --------------- + .. function:: add_key([**kwargs]) -.. module:: pskc.key + Add a new key to the PSKC instance. The keyword arguments may refer to + any attributes of the :class:`~pskc.key.Key` class with which the new + key is initialised. -The :attr:`~pskc.PSKC.keys` attribute of a :class:`~pskc.PSKC` instance -provides access to a list of keys contained in the PSKC file. :class:`Key` -instances provide access to a number of attributes that provide information -on the transmitted keys:: + .. function:: write(filename) - >>> pskc = PSKC('somefile.pskcxml') - >>> first_key = pskc.keys[0] - >>> first_key.id - 'some-id' - >>> first_key.algorithm - 'urn:ietf:params:xml:ns:keyprov:pskc:hotp' - >>> first_key.secret - 'SOME_SECRET_VALUE' + Write the PSKC object to the provided file. The `filename` argument can + be either the name of a file or a file-like object. -Attribute values will be ``None`` if it the value is not present in the PSKC -file. If any of the :attr:`~pskc.key.Key.secret`, -:attr:`~pskc.key.Key.counter`, :attr:`~pskc.key.Key.time_offset`, -:attr:`~pskc.key.Key.time_interval` or :attr:`~pskc.key.Key.time_drift` -values are accessed while they are encrypted and decryption is unsuccessful a -:exc:`~pskc.exceptions.DecryptionError` exception is raised. +The Key class +------------- + +.. module:: pskc.key .. class:: Key() + Instances of this class provide the following attributes and functions: + .. attribute:: id A unique identifier for the key. If there are multiple interactions @@ -97,15 +139,18 @@ values are accessed while they are encrypted and decryption is unsuccessful a associates specific semantics to the key. Some `known profiles `__ are: - * ``urn:ietf:params:xml:ns:keyprov:pskc:pin``: - `Symmetric static credential comparison `_ - * ``urn:ietf:params:xml:ns:keyprov:pskc:hotp``: - `OATH event-based OTP `_ - * ``urn:ietf:params:xml:ns:keyprov:pskc#totp`` or - ``urn:ietf:params:xml:ns:keyprov:pskc:totp``: - `OATH time-based OTP `_ - * ``urn:ietf:params:xml:ns:keyprov:pskc#OCRA-1``: - `OATH challenge-response algorithm `_ + +------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+ + | URI | Purpose | + +================================================+=============================================================================================================================+ + | ``urn:ietf:params:xml:ns:keyprov:pskc:pin`` | `Symmetric static credential comparison `_ | + +------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+ + | ``urn:ietf:params:xml:ns:keyprov:pskc:hotp`` | `OATH event-based OTP `_ | + +------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+ + | ``urn:ietf:params:xml:ns:keyprov:pskc#totp`` | `OATH time-based OTP `_ | + | ``urn:ietf:params:xml:ns:keyprov:pskc:totp`` | | + +------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+ + | ``urn:ietf:params:xml:ns:keyprov:pskc#OCRA-1`` | `OATH challenge-response algorithm `_ | + +------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+ .. attribute:: secret @@ -116,28 +161,28 @@ values are accessed while they are encrypted and decryption is unsuccessful a .. attribute:: counter - The event counter for event-based OTP algorithms. Will also be + The event counter (integer) for event-based OTP algorithms. Will also be transparently decrypted and may also raise :exc:`~pskc.exceptions.DecryptionError`. .. attribute:: time_offset - The time offset offset for time-based OTP algorithms. If time intervals - are used it carries the number of time intervals passed from an - algorithm-dependent start point. Will also be transparently decrypted + The time offset (integer) for time-based OTP algorithms. If time + intervals are used it carries the number of time intervals passed from + an algorithm-dependent start point. Will also be transparently decrypted and may also raise :exc:`~pskc.exceptions.DecryptionError`. .. attribute:: time_interval - The time interval in seconds for time-based OTP algorithms (usually - ``30`` or ``60``). Will also be transparently decrypted and may also - raise :exc:`~pskc.exceptions.DecryptionError`. + The time interval in seconds (integer) for time-based OTP algorithms + (usually ``30`` or ``60``). Will also be transparently decrypted and may + also raise :exc:`~pskc.exceptions.DecryptionError`. .. attribute:: time_drift For time-based OTP algorithms this contains the device clock drift in - number of intervals. Will also be transparently decrypted and may also - raise :exc:`~pskc.exceptions.DecryptionError`. + number of intervals (integer). Will also be transparently decrypted and + may also raise :exc:`~pskc.exceptions.DecryptionError`. .. attribute:: issuer @@ -186,7 +231,7 @@ values are accessed while they are encrypted and decryption is unsuccessful a .. attribute:: model - A manufacturer specific description of the model of the device. + A manufacturer-specific description of the model of the device. .. attribute:: issue_no @@ -223,8 +268,8 @@ values are accessed while they are encrypted and decryption is unsuccessful a .. attribute:: algorithm_suite - Additional algorithm specific characteristics. For example, in an - HMAC-based algorithm it could designate the hash algorithm used (SHA1 + Additional algorithm-specific characteristics. For example, in an + HMAC-based algorithm it could specify the hash algorithm used (SHA1 or SHA256). .. attribute:: challenge_encoding @@ -249,7 +294,7 @@ values are accessed while they are encrypted and decryption is unsuccessful a .. attribute:: challenge_check Boolean that indicates whether the device will check an embedded - `Luhn check digit `_ + `Luhn check digit `_ contained in the challenge. .. attribute:: response_encoding @@ -264,7 +309,7 @@ values are accessed while they are encrypted and decryption is unsuccessful a .. attribute:: response_check Boolean that indicates whether the device will append a - `Luhn check digit `_ + `Luhn check digit `_ to the response. .. attribute:: policy -- cgit v1.2.3