[Python-modules-commits] [python-pskc] 01/09: Import python-pskc_0.3.orig.tar.gz
Arthur de Jong
adejong at moszumanska.debian.org
Mon Mar 28 20:06:36 UTC 2016
This is an automated email from the git hooks/post-receive script.
adejong pushed a commit to branch master
in repository python-pskc.
commit e9792624ef7adb550500faeb118bb0c7d9f73e39
Author: Arthur de Jong <adejong at debian.org>
Date: Mon Mar 28 21:16:07 2016 +0200
Import python-pskc_0.3.orig.tar.gz
---
ChangeLog | 126 +++++++++++++++++++++++++++++
MANIFEST.in | 2 +-
NEWS | 10 +++
PKG-INFO | 16 ++--
README | 7 +-
docs/conf.py | 2 +-
docs/encryption.rst | 12 ++-
docs/exceptions.rst | 6 +-
docs/mac.rst | 28 ++++---
docs/policy.rst | 27 +++++--
docs/usage.rst | 151 ++++++++++++++++++++++-------------
pskc/__init__.py | 33 +++++---
pskc/crypto/__init__.py | 0
pskc/{ => crypto}/aeskw.py | 22 +++---
pskc/{ => crypto}/tripledeskw.py | 10 ++-
pskc/encryption.py | 30 +++----
pskc/key.py | 150 ++++++++++++++++++++++++++---------
pskc/mac.py | 4 +-
pskc/parse.py | 102 ------------------------
pskc/policy.py | 32 +++++++-
pskc/xml.py | 166 +++++++++++++++++++++++++++++++++++++++
pskc2csv.py | 127 ++++++++++++++++++++++++++++++
python_pskc.egg-info/PKG-INFO | 16 ++--
python_pskc.egg-info/SOURCES.txt | 11 ++-
python_pskc.egg-info/pbr.json | 1 +
setup.py | 10 ++-
tests/SampleFullyQualifiedNS.xml | 100 +++++++++++++++++++++++
tests/test_aeskw.doctest | 79 ++++++++++---------
tests/test_draft_keyprov.doctest | 13 +--
tests/test_encryption.doctest | 59 ++++++++------
tests/test_invalid.doctest | 11 +--
tests/test_misc.doctest | 31 +++++++-
tests/test_rfc6030.doctest | 33 +++++---
tests/test_tripledeskw.doctest | 9 ++-
tests/test_write.doctest | 145 ++++++++++++++++++++++++++++++++++
35 files changed, 1197 insertions(+), 384 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index b8a8d1d..6a16e2c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,129 @@
+2015-10-07 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [cf0c9e6] README, docs/conf.py, docs/encryption.rst,
+ docs/exceptions.rst, docs/mac.rst, docs/policy.rst, docs/usage.rst,
+ pskc/__init__.py: 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.
+
+2015-10-06 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [671b6e2] pskc/__init__.py, pskc/crypto/aeskw.py,
+ pskc/crypto/tripledeskw.py, pskc/encryption.py, pskc/key.py,
+ pskc/policy.py, pskc/xml.py, setup.py, tests/test_aeskw.doctest,
+ tests/test_draft_keyprov.doctest, tests/test_encryption.doctest,
+ tests/test_invalid.doctest, tests/test_misc.doctest,
+ tests/test_rfc6030.doctest, tests/test_tripledeskw.doctest,
+ tests/test_write.doctest: Support Python 3
+
+ This enables support for Python 3 together with Python 2 support
+ with a single codebase.
+
+ On Python 3 key data is passed around as bytestrings which makes
+ the doctests a little harder to maintain across Python versions.
+
+2015-10-06 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [68b20e2] pskc/encryption.py, pskc/xml.py,
+ tests/SampleFullyQualifiedNS.xml, tests/test_misc.doctest:
+ Fix issue with namespaced PBKDF2 parameters
+
+ The find() utility functions now allow specifying multiple paths
+ to be searched where the first match is returned.
+
+ This allows handling PSKC files where the PBKDF2 salt, iteration
+ count, key length and PRF elements are prefixed with the xenc11
+ namespace.
+
+ A test including such a PSKC file has been included.
+
+ Thanks to Eric Plet for reporting this.
+
+2014-10-12 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [ebe46f2] pskc2csv.py: Provide a sample pskc2csv script
+
+ This is a simple command-line utility that reads a PSKC file
+ and outputs information on keys as CSV.
+
+2014-06-30 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [1363564] pskc/aeskw.py, pskc/crypto/__init__.py,
+ pskc/crypto/aeskw.py, pskc/crypto/tripledeskw.py,
+ pskc/encryption.py, pskc/tripledeskw.py, tests/test_aeskw.doctest,
+ tests/test_tripledeskw.doctest: Move encryption functions in
+ pskc.crypto package
+
+ This moves the encryption functions under the pskc.crypto package
+ to more clearly separate it from the other code. Ideally this
+ should be replaced by third-party library code.
+
+2014-06-30 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [e468ebe] pskc/__init__.py, pskc/encryption.py, pskc/key.py,
+ pskc/mac.py, pskc/parse.py, pskc/policy.py, pskc/xml.py: Rename
+ pskc.parse to pskc.xml
+
+ This renames the parse module to xml to better reflect the
+ purpose of the module and it's functions.
+
+ This also introduces a parse() function that wraps etree.parse().
+
+2014-06-28 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [480e2d0] : Support writing unencrypted PSKC files
+
+2014-06-27 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [37dc64a] tests/test_write.doctest: Add test for writing PSKC files
+
+ This makes a simple doctest that checks the writing of the XML
+ representation of the PSKC data.
+
+2014-06-27 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [865a755] pskc/__init__.py, pskc/parse.py: Add function for
+ writing XML
+
+ This provides a function for pretty-printing the generated
+ XML document.
+
+2014-06-27 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [61a192f] pskc/__init__.py, pskc/key.py, pskc/policy.py: Construct
+ XML document with basic PKSC information
+
+ This introduces make_xml() functions to build an XML document
+ that contains the basic PSKC information and keys. This currently
+ only supports writing unencrypted PSKC files.
+
+2014-06-27 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [69aec9f] pskc/parse.py: Introduce mk_elem() to create elements
+
+ This introduces the mk_elem() function that can be used to create
+ ElementTree elements for building XML documents. This function
+ transparetly handles namespaces, translation of values into
+ XML etc.
+
+2014-06-27 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [7591271] pskc/key.py: Simplify DataType value handling
+
+ Only store the native value of the property, not the text
+ representation. This also results in the BinaryDataType and
+ IntegerDataType subclasses only needing from_text() and from_bin()
+ functions.
+
+2014-06-19 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [09eb6b3] ChangeLog, NEWS, docs/changes.rst, docs/index.rst,
+ docs/usage.rst, pskc/__init__.py, setup.py: Get files ready for
+ 0.2 release
+
2014-06-19 Arthur de Jong <arthur at arthurdejong.org>
* [62c9af4] pskc/__init__.py: Only catch normal exceptions
diff --git a/MANIFEST.in b/MANIFEST.in
index 217a0fd..6eb0c88 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,3 +1,3 @@
include README NEWS ChangeLog COPYING *.py
-recursive-include tests *.doctest *.py *.pskcxml
+recursive-include tests *.doctest *.py *.pskcxml *.xml
recursive-include docs *.rst *.py
diff --git a/NEWS b/NEWS
index 4318931..3200bce 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,13 @@
+changes from 0.2 to 0.3
+-----------------------
+
+* support writing unencrypted PSKC files
+* include a sample pskc2csv script in the source code
+* fix an issue with XML namespaces for PBKDF2 parameters
+* support Python 3
+* update documentation
+
+
changes from 0.1 to 0.2
-----------------------
diff --git a/PKG-INFO b/PKG-INFO
index c001dfc..0b63ca7 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: python-pskc
-Version: 0.2
+Version: 0.3
Summary: Python module for handling PSKC files
Home-page: http://arthurdejong.org/python-pskc/
Author: Arthur de Jong
@@ -22,23 +22,25 @@ Description: Python module for handling PSKC files
>>> pskc = PSKC('tests/rfc6030-figure7.pskcxml')
>>> pskc.encryption.derive_key('qwerty')
>>> for key in pskc.keys:
- ... print key.serial, key.secret
+ ... print('%s %s' % (key.serial, str(key.secret.decode())))
987654321 12345678901234567890
- The module should be able to handle most common PSKC files. Checking embedded
- signatures, asymmetric keys and writing files are on the wishlist (patches
- welcome).
+ The module should be able to handle most common PSKC files.
+Keywords: PSKC,RFC 6030,key container
Platform: UNKNOWN
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
+Classifier: Intended Audience :: Information Technology
Classifier: Intended Audience :: System Administrators
-Classifier: License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)
+Classifier: License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
-Classifier: Topic :: Security :: Cryptography
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Text Processing :: Markup :: XML
diff --git a/README b/README
index 5573c77..7dd7ea0 100644
--- a/README
+++ b/README
@@ -8,8 +8,7 @@ types of crypto modules. The format is commonly used for one-time password
tokens or other authentication devices.
The goal of this module is mainly to provide parsing of PSKC files in order
-to extract secret keys for use in an OTP authentication system. At a later
-time support for writing files may be added.
+to extract secret keys for use in an OTP authentication system.
http://arthurdejong.org/python-pskc/
@@ -20,7 +19,7 @@ API
The module provides a straightforward API that is mostly geared towards
parsing existing PSKC files.
-Extracting key matarial from PSKC files is as simple as.
+Extracting key matarial from encrypted PSKC files is as simple as.
>>> from pskc import PSKC
>>> pskc = PSKC('tests/rfc6030-figure7.pskcxml')
@@ -45,7 +44,7 @@ private key material.
Copyright
---------
-Copyright (C) 2014 Arthur de Jong
+Copyright (C) 2014-2015 Arthur de Jong
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
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
<https://tools.ietf.org/html/rfc6030#section-6.1.1>`_ 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 <https://tools.ietf.org/html/rfc6030#section-5>`__.
+The PSKC format allows for specifying `key and pin usage policy <https://tools.ietf.org/html/rfc6030#section-5>`__
+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
<https://www.iana.org/assignments/pskc/#key-usage>`__ 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-use-constants>`.
+ 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 <pin-use-constants>`.
+ 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 <key-use-constants>`.
+ :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
<https://www.iana.org/assignments/pskc/#alg-profiles>`__ are:
- * ``urn:ietf:params:xml:ns:keyprov:pskc:pin``:
- `Symmetric static credential comparison <https://tools.ietf.org/html/rfc6030#section-10.2>`_
- * ``urn:ietf:params:xml:ns:keyprov:pskc:hotp``:
- `OATH event-based OTP <https://tools.ietf.org/html/rfc6030#section-10.1>`_
- * ``urn:ietf:params:xml:ns:keyprov:pskc#totp`` or
- ``urn:ietf:params:xml:ns:keyprov:pskc:totp``:
- `OATH time-based OTP <http://tools.ietf.org/html/draft-hoyer-keyprov-pskc-algorithm-profiles-01#section-4>`_
- * ``urn:ietf:params:xml:ns:keyprov:pskc#OCRA-1``:
- `OATH challenge-response algorithm <https://tools.ietf.org/html/draft-hoyer-keyprov-pskc-algorithm-profiles-01#section-3>`_
+ +------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+
+ | URI | Purpose |
+ +================================================+=============================================================================================================================+
+ | ``urn:ietf:params:xml:ns:keyprov:pskc:pin`` | `Symmetric static credential comparison <https://tools.ietf.org/html/rfc6030#section-10.2>`_ |
+ +------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+
+ | ``urn:ietf:params:xml:ns:keyprov:pskc:hotp`` | `OATH event-based OTP <https://tools.ietf.org/html/rfc6030#section-10.1>`_ |
+ +------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+
+ | ``urn:ietf:params:xml:ns:keyprov:pskc#totp`` | `OATH time-based OTP <http://tools.ietf.org/html/draft-hoyer-keyprov-pskc-algorithm-profiles-01#section-4>`_ |
+ | ``urn:ietf:params:xml:ns:keyprov:pskc:totp`` | |
+ +------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+
+ | ``urn:ietf:params:xml:ns:keyprov:pskc#OCRA-1`` | `OATH challenge-response algorithm <https://tools.ietf.org/html/draft-hoyer-keyprov-pskc-algorithm-profiles-01#section-3>`_ |
+ +------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+
.. 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 <http://arthurdejong.org/python-stdnum/doc/0.9/stdnum.luhn.html>`_
+ `Luhn check digit <http://arthurdejong.org/python-stdnum/doc/stdnum.luhn.html>`_
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 <http://arthurdejong.org/python-stdnum/doc/0.9/stdnum.luhn.html>`_
+ `Luhn check digit <http://arthurdejong.org/python-stdnum/doc/stdnum.luhn.html>`_
to the response.
.. attribute:: policy
diff --git a/pskc/__init__.py b/pskc/__init__.py
index 61fa9fe..685843b 100644
--- a/pskc/__init__.py
+++ b/pskc/__init__.py
@@ -1,7 +1,7 @@
# __init__.py - main module
# coding: utf-8
#
-# Copyright (C) 2014 Arthur de Jong
+# Copyright (C) 2014-2015 Arthur de Jong
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -34,12 +34,10 @@ The following prints all keys, decrypting using a password:
>>> pskc = PSKC('tests/rfc6030-figure7.pskcxml')
>>> pskc.encryption.derive_key('qwerty')
>>> for key in pskc.keys:
-... print key.serial, key.secret
+... print('%s %s' % (key.serial, str(key.secret.decode())))
987654321 12345678901234567890
-The module should be able to handle most common PSKC files. Checking embedded
-signatures, asymmetric keys and writing files are on the wishlist (patches
-welcome).
+The module should be able to handle most common PSKC files.
"""
@@ -47,7 +45,7 @@ __all__ = ['PSKC', '__version__']
# the version number of the library
-__version__ = '0.2'
+__version__ = '0.3'
class PSKC(object):
@@ -72,9 +70,9 @@ class PSKC(object):
self.mac = MAC(self)
self.keys = []
if filename is not None:
- from pskc.parse import etree
+ from pskc.xml import parse
try:
- tree = etree.parse(filename)
+ tree = parse(filename)
except Exception:
raise ParseError('Error parsing XML')
self.parse(tree.getroot())
@@ -85,7 +83,7 @@ class PSKC(object):
"""Read information from the provided <KeyContainer> tree."""
from pskc.exceptions import ParseError
from pskc.key import Key
- from pskc.parse import find, findall
+ from pskc.xml import find, findall
if not container.tag.endswith('KeyContainer'):
raise ParseError('Missing KeyContainer')
# the version of the PSKC schema
@@ -102,6 +100,14 @@ class PSKC(object):
for key_package in findall(container, 'pskc:KeyPackage'):
self.keys.append(Key(self, key_package))
+ def make_xml(self):
+ from pskc.xml import mk_elem
+ container = mk_elem('pskc:KeyContainer', Version=self.version,
+ Id=self.id)
+ for key in self.keys:
+ key.make_xml(container)
+ return container
+
def add_key(self, **kwargs):
"""Create a new key instance for the PSKC file.
@@ -116,3 +122,12 @@ class PSKC(object):
raise AttributeError()
setattr(key, k, v)
return key
+
+ def write(self, filename):
+ """Write the PSKC file to the provided file."""
+ from pskc.xml import tostring
+ if hasattr(filename, 'write'):
+ filename.write(tostring(self.make_xml()))
+ else:
+ with open(filename, 'wb') as output:
+ self.write(output)
diff --git a/pskc/crypto/__init__.py b/pskc/crypto/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/pskc/aeskw.py b/pskc/crypto/aeskw.py
similarity index 88%
rename from pskc/aeskw.py
rename to pskc/crypto/aeskw.py
index 24e90b0..eeafed1 100644
--- a/pskc/aeskw.py
+++ b/pskc/crypto/aeskw.py
@@ -1,7 +1,7 @@
# aeskw.py - implementation of AES key wrapping
# coding: utf-8
#
-# Copyright (C) 2014 Arthur de Jong
+# Copyright (C) 2014-2015 Arthur de Jong
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -20,6 +20,8 @@
"""Implement key wrapping as described in RFC 3394 and RFC 5649."""
+import binascii
+
from Crypto.Cipher import AES
from Crypto.Util.number import bytes_to_long, long_to_bytes
from Crypto.Util.strxor import strxor
@@ -31,8 +33,8 @@ def _split(value):
return value[:8], value[8:]
-RFC3394_IV = 'a6a6a6a6a6a6a6a6'.decode('hex')
-RFC5649_IV = 'a65959a6'.decode('hex')
+RFC3394_IV = binascii.a2b_hex('a6a6a6a6a6a6a6a6')
+RFC5649_IV = binascii.a2b_hex('a65959a6')
def wrap(plaintext, key, iv=None, pad=None):
@@ -54,7 +56,7 @@ def wrap(plaintext, key, iv=None, pad=None):
raise EncryptionError('Plaintext length wrong')
if mli % 8 != 0 and pad is not False:
r = (mli + 7) // 8
- plaintext += ((r * 8) - mli) * '\0'
+ plaintext += ((r * 8) - mli) * b'\0'
if iv is None:
if len(plaintext) != mli or pad is True:
@@ -63,7 +65,7 @@ def wrap(plaintext, key, iv=None, pad=None):
iv = RFC3394_IV
encrypt = AES.new(key).encrypt
- n = len(plaintext) / 8
+ n = len(plaintext) // 8
if n == 1:
# RFC 5649 shortcut
@@ -76,7 +78,7 @@ def wrap(plaintext, key, iv=None, pad=None):
for i in range(n):
A, R[i] = _split(encrypt(A + R[i]))
A = strxor(A, long_to_bytes(n * j + i + 1, 8))
- return A + ''.join(R)
+ return A + b''.join(R)
def unwrap(ciphertext, key, iv=None, pad=None):
@@ -95,7 +97,7 @@ def unwrap(ciphertext, key, iv=None, pad=None):
raise DecryptionError('Ciphertext length wrong')
decrypt = AES.new(key).decrypt
- n = len(ciphertext) / 8 - 1
+ n = len(ciphertext) // 8 - 1
if n == 1:
A, plaintext = _split(decrypt(ciphertext))
@@ -107,16 +109,16 @@ def unwrap(ciphertext, key, iv=None, pad=None):
for i in reversed(range(n)):
A = strxor(A, long_to_bytes(n * j + i + 1, 8))
A, R[i] = _split(decrypt(A + R[i]))
- plaintext = ''.join(R)
+ plaintext = b''.join(R)
if iv is None:
if A == RFC3394_IV and pad is not True:
return plaintext
elif A[:4] == RFC5649_IV and pad is not False:
mli = bytes_to_long(A[4:])
- # check padding length is valid and only contains zeros
+ # check padding length is valid and plaintext only contains zeros
if 8 * (n - 1) < mli <= 8 * n and \
- all(x == '\0' for x in plaintext[mli:]):
+ plaintext.endswith((len(plaintext) - mli) * b'\0'):
return plaintext[:mli]
elif A == iv:
return plaintext
diff --git a/pskc/tripledeskw.py b/pskc/crypto/tripledeskw.py
similarity index 92%
rename from pskc/tripledeskw.py
rename to pskc/crypto/tripledeskw.py
index 47c93f1..a135ebd 100644
--- a/pskc/tripledeskw.py
+++ b/pskc/crypto/tripledeskw.py
@@ -1,7 +1,7 @@
# tripledeskw.py - implementation of Triple DES key wrapping
# coding: utf-8
#
-# Copyright (C) 2014 Arthur de Jong
+# Copyright (C) 2014-2015 Arthur de Jong
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -20,6 +20,8 @@
"""Implement Triple DES key wrapping as described in RFC 3217."""
+import binascii
+
from Crypto import Random
from Crypto.Cipher import DES3
from Crypto.Hash import SHA
@@ -32,7 +34,7 @@ def _cms_hash(value):
return SHA.new(value).digest()[:8]
-RFC3217_IV = '4adda22c79e82105'.decode('hex')
+RFC3217_IV = binascii.a2b_hex('4adda22c79e82105')
def wrap(plaintext, key, iv=None):
@@ -48,7 +50,7 @@ def wrap(plaintext, key, iv=None):
cipher = DES3.new(key, DES3.MODE_CBC, iv)
tmp = iv + cipher.encrypt(plaintext + _cms_hash(plaintext))
cipher = DES3.new(key, DES3.MODE_CBC, RFC3217_IV)
- return cipher.encrypt(''.join(reversed(tmp)))
+ return cipher.encrypt(tmp[::-1])
def unwrap(ciphertext, key):
@@ -59,7 +61,7 @@ def unwrap(ciphertext, key):
if len(ciphertext) % DES3.block_size != 0:
raise DecryptionError('Ciphertext length wrong')
cipher = DES3.new(key, DES3.MODE_CBC, RFC3217_IV)
- tmp = ''.join(reversed(cipher.decrypt(ciphertext)))
+ tmp = cipher.decrypt(ciphertext)[::-1]
cipher = DES3.new(key, DES3.MODE_CBC, tmp[:8])
tmp = cipher.decrypt(tmp[8:])
if tmp[-8:] == _cms_hash(tmp[:-8]):
diff --git a/pskc/encryption.py b/pskc/encryption.py
index b57053c..4911662 100644
--- a/pskc/encryption.py
+++ b/pskc/encryption.py
@@ -1,7 +1,7 @@
# encryption.py - module for handling encrypted values
# coding: utf-8
#
-# Copyright (C) 2014 Arthur de Jong
+# Copyright (C) 2014-2015 Arthur de Jong
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -30,7 +30,7 @@ The encryption key can be derived using the KeyDerivation class.
def unpad(value):
"""Remove padding from the plaintext."""
- return value[0:-ord(value[-1])]
+ return value[0:-ord(value[-1:])]
class EncryptedValue(object):
@@ -51,7 +51,7 @@ class EncryptedValue(object):
def parse(self, encrypted_value):
"""Read encrypted data from the <EncryptedValue> XML tree."""
- from pskc.parse import find, findbin
+ from pskc.xml import find, findbin
if encrypted_value is None:
return
encryption_method = find(encrypted_value, 'xenc:EncryptionMethod')
@@ -92,14 +92,14 @@ class EncryptedValue(object):
elif self.algorithm.endswith('#kw-aes128') or \
self.algorithm.endswith('#kw-aes192') or \
self.algorithm.endswith('#kw-aes256'):
- from pskc.aeskw import unwrap
+ from pskc.crypto.aeskw import unwrap
from Crypto.Cipher import AES
if len(key) * 8 != int(self.algorithm[-3:]) or \
len(key) not in AES.key_size:
raise DecryptionError('Invalid key length')
return unwrap(self.cipher_value, key)
elif self.algorithm.endswith('#kw-tripledes'):
- from pskc.tripledeskw import unwrap
+ from pskc.crypto.tripledeskw import unwrap
... 1790 lines suppressed ...
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-pskc.git
More information about the Python-modules-commits
mailing list