[Python-modules-commits] [python-pskc] 03/09: Import python-pskc_0.4.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 816c2f20158a9148204b5dfcbd0e0a924c545483
Author: Arthur de Jong <adejong at debian.org>
Date: Mon Mar 28 21:30:28 2016 +0200
Import python-pskc_0.4.orig.tar.gz
---
ChangeLog | 356 +++++++++++++++++
NEWS | 18 +
PKG-INFO | 10 +-
README | 25 +-
docs/conf.py | 2 +-
docs/encryption.rst | 86 ++++-
docs/mac.rst | 11 +
docs/policy.rst | 8 +-
docs/usage.rst | 25 +-
pskc/__init__.py | 32 +-
pskc/encryption.py | 419 +++++++++++++++------
pskc/key.py | 247 ++++++++----
pskc/mac.py | 175 ++++++---
pskc/policy.py | 62 ++-
pskc/xml.py | 59 ++-
pskc2csv.py | 52 ++-
python_pskc.egg-info/PKG-INFO | 10 +-
python_pskc.egg-info/SOURCES.txt | 68 ++--
python_pskc.egg-info/pbr.json | 1 -
setup.py | 4 +-
.../actividentity-3des.pskcxml} | 0
.../ocra.pskcxml} | 0
.../securid-aes-counter.pskcxml} | 0
.../totp.pskcxml} | 0
tests/{ => encryption}/aes128-cbc.pskcxml | 0
tests/{ => encryption}/aes192-cbc.pskcxml | 0
tests/{ => encryption}/aes256-cbc.pskcxml | 0
tests/{ => encryption}/kw-aes128.pskcxml | 0
tests/{ => encryption}/kw-aes192.pskcxml | 0
tests/{ => encryption}/kw-aes256.pskcxml | 0
tests/{ => encryption}/kw-tripledes.pskcxml | 0
tests/{ => encryption}/tripledes-cbc.pskcxml | 0
tests/feitian/20120919-test001-4282.xml | 58 +++
tests/feitian/file1.pskcxml | 158 ++++++++
.../mac-algorithm.pskcxml} | 0
.../mac-value.pskcxml} | 0
.../missing-encryption.pskcxml} | 13 +-
.../no-mac-method.pskcxml} | 0
tests/invalid/not-boolean.pskcxml | 15 +
tests/invalid/not-integer.pskcxml | 15 +
tests/invalid/not-integer2.pskcxml | 15 +
.../notxml.pskcxml} | 0
.../unknown-encryption.pskcxml} | 18 +-
.../wrongelement.pskcxml} | 0
.../wrongversion.pskcxml} | 0
tests/{ => misc}/SampleFullyQualifiedNS.xml | 0
tests/misc/checkdigits.pskcxml | 54 +++
tests/misc/integers.pskcxml | 47 +++
tests/{ => misc}/odd-namespace.pskcxml | 0
tests/misc/policy.pskcxml | 81 ++++
tests/nagraid/file1.pskcxml | 114 ++++++
.../figure10.pskcxml} | 0
.../figure2.pskcxml} | 0
.../figure3.pskcxml} | 0
.../figure4.pskcxml} | 0
.../figure5.pskcxml} | 0
.../figure6.pskcxml} | 0
.../figure7.pskcxml} | 0
tests/test_aeskw.doctest | 10 +-
tests/test_draft_keyprov.doctest | 8 +-
tests/test_encryption.doctest | 119 +++++-
tests/test_invalid.doctest | 84 +++--
tests/test_misc.doctest | 131 ++++++-
tests/test_rfc6030.doctest | 36 +-
tests/test_tripledeskw.doctest | 8 +-
tests/test_vendors.doctest | 104 +++++
tests/test_write.doctest | 285 +++++++++++++-
67 files changed, 2572 insertions(+), 471 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 6a16e2c..3300fd9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,359 @@
+2016-03-26 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [0c57335] docs/policy.rst: Document may_use() policy function
+
+2016-03-27 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [b4a6c72] : Implement writing encrypted files
+
+ This adds support for setting up encryption keys and password-based
+ key derivation when writing PSKC files. Also MAC keys are set
+ up when needed.
+
+2016-03-26 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [59aa65b] README, docs/conf.py, docs/encryption.rst, docs/mac.rst,
+ docs/usage.rst, pskc/__init__.py: Document writing encrypted files
+
+2016-03-21 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [5f32528] tests/test_write.doctest: Add encryption error tests
+
+2016-03-21 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [7ede4a1] tests/test_write.doctest: Add tests for writing
+ encrypted PSKC files
+
+2016-03-20 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [1ff3237] pskc/encryption.py: Allow configuring a pre-shared key
+
+ This method allows configuring a pre-shared encryption key and
+ will chose reasonable defaults for needed encryption values
+ (e.g. it will choose an algorithm, generate a new key of the
+ appropriate length if needed, etc.).
+
+2016-03-19 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [50414a3] pskc/encryption.py, tests/test_encryption.doctest:
+ Allow configuring PBKDF2 key derivation
+
+ This factors out the PBKDF2 key derivation to a separate function
+ and introduces a function to configure KeyDerivation instances
+ with PBKDF2.
+
+2016-03-21 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [5ac9d43] pskc/mac.py, tests/test_encryption.doctest: Allow
+ configuring a MAC key
+
+ This method will set up a MAC key and algorithm as specified or
+ use reasonable defauts.
+
+2016-03-20 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [16da531] pskc/key.py, pskc/mac.py: Generate MAC values
+
+2016-03-20 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [ca0fa36] pskc/__init__.py, pskc/encryption.py, pskc/mac.py:
+ Write MACMethod
+
+ This also makes the MAC.algorithm a property similarly as what
+ is done for Encryption (normalise algorithm names) and adds a
+ setter for the MAC.key property.
+
+2016-03-21 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [8fd35ba] pskc/encryption.py, pskc/key.py: Write out encrypted
+ values
+
+ The Encryption class now has a fields property that lists the
+ fields that should be encrypted when writing the PSKC file.
+
+ This adds an encrypt_value() function that performs the encryption
+ and various functions to convert the plain value to binary before
+ writing the encrypted XML elements.
+
+2016-03-20 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [eba541e] pskc/__init__.py, pskc/encryption.py, pskc/mac.py:
+ Make Encryption and MAC constructors consistent
+
+ This removes calling parse() from the Encryption and MAC
+ constructors and stores a reference to the PSKC object in both
+ objects so it can be used later on.
+
+2016-03-20 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [fe21231] pskc/__init__.py, pskc/encryption.py,
+ tests/test_write.doctest: Write encryption key information
+
+ This writes information about a pre-shared key or PBKDF2 key
+ derivation in the PSKC file. This also means that writing
+ a decrypted version of a previously encrypted file requires
+ actively removing the encryption.
+
+2016-03-19 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [0893640] pskc/encryption.py, tests/test_misc.doctest: Add
+ algorithm_key_lengths property
+
+ This property on the Encryption object provides a list of key
+ sizes (in bytes) that the configured encryption algorithm supports.
+
+2016-03-22 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [8b5f6c2] pskc/policy.py, tests/test_misc.doctest,
+ tests/test_rfc6030.doctest, tests/test_write.doctest: Also check
+ key expiry in may_use()
+
+2016-03-20 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [dfa57ae] pskc2csv.py: Support reading password or key in pskc2csv
+
+ This supports reading the encryption password or key from the
+ command line or from a file.
+
+2014-06-28 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [0744222] pskc/xml.py: Copy namespaces to toplevel element
+
+ Ensure that when writing an XML file all namespace definitions
+ are on the toplevel KeyContainer element instead of scattered
+ throughout the XML document.
+
+2016-03-19 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [e8ef157] pskc/__init__.py, tests/test_write.doctest: Support
+ writing to text streams in Python 3
+
+ This supports writing the XML output to binary streams as well
+ as text streams in Python 3.
+
+2016-03-19 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [cadc6d9] pskc/key.py, pskc/mac.py,
+ tests/invalid/encryption.pskcxml,
+ tests/invalid/missing-encryption.pskcxml,
+ tests/invalid/not-boolean.pskcxml,
+ tests/invalid/not-integer.pskcxml,
+ tests/invalid/not-integer2.pskcxml,
+ tests/invalid/unknown-encryption.pskcxml, tests/test_aeskw.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:
+ Improve tests and test coverage
+
+ This adds tests to ensure that incorrect attribute and value
+ types in the PSKC file raise a ValueError exception and extends
+ the tests for invalid encryption options.
+
+ This removes some code or adds no cover directives to a few
+ places that have unreachable code or are Python version specific
+ and places doctest directives inside the doctests where needed.
+
+2016-03-19 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [b8905e0] pskc/key.py, pskc/xml.py, tests/misc/checkdigits.pskcxml,
+ tests/test_misc.doctest: Support both CheckDigit and CheckDigits
+
+ RFC 6030 is not clear about whether the attribute of
+ ChallengeFormat and ResponseFormat should be the singular
+ CheckDigit or the plural CheckDigits. This ensures that both
+ forms are accepted.
+
+2016-03-19 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [7915c55] pskc/policy.py, tests/misc/policy.pskcxml,
+ tests/test_misc.doctest: Implement policy checking
+
+ This checks for unknown policy elements in the PSKC file and
+ will cause the key usage policy check to fail.
+
+2016-03-18 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [1687fd6] tests/feitian/20120919-test001-4282.xml,
+ tests/feitian/file1.pskcxml, tests/nagraid/file1.pskcxml,
+ tests/test_vendors.doctest: Add a few tests for vendor files
+
+ Some vendor-specific files were lifted from the LinOTP test suite
+ and another Feitian file was found in the oath-toolkit repository.
+
+2016-01-31 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [aae8a18] pskc/key.py, tests/misc/integers.pskcxml,
+ tests/test_misc.doctest: Support various integer representations
+
+ This extends support for handling various encoding methods for
+ integer values in PSKC files. For encrypted files the decrypted
+ value is first tried to be evaluated as an ASCII representation
+ of the number and after that big-endian decoded.
+
+ For plaintext values first ASCII decoding is tried after which
+ base64 decoding is tried which tries the same encodings as for
+ decrypted values.
+
+ There should be no possibility for any base64 encoded value
+ (either of an ASCII value or a big-endian value) to be interpreted
+ as an ASCII value for any 32-bit integer.
+
+ There is a possibility that a big-endian encoded integer could
+ be incorrectly interpreted as an ASCII value but this is only
+ the case for 110 numbers when only considering 6-digit numbers.
+
+2016-01-24 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [c86aaea] README, pskc/__init__.py,
+ tests/SampleFullyQualifiedNS.xml, tests/aes128-cbc.pskcxml,
+ tests/aes192-cbc.pskcxml, tests/aes256-cbc.pskcxml,
+ tests/draft-hoyer-keyprov-pskc-algorithm-profiles-01/actividentity-3des.pskcxml,
+ tests/draft-hoyer-keyprov-pskc-algorithm-profiles-01/ocra.pskcxml,
+ tests/draft-hoyer-keyprov-pskc-algorithm-profiles-01/securid-aes-counter.pskcxml,
+ tests/draft-hoyer-keyprov-pskc-algorithm-profiles-01/totp.pskcxml,
+ tests/draft-keyprov-actividentity-3des.pskcxml,
+ tests/draft-keyprov-ocra.pskcxml,
+ tests/draft-keyprov-securid-aes-counter.pskcxml,
+ tests/draft-keyprov-totp.pskcxml,
+ tests/encryption/aes128-cbc.pskcxml,
+ tests/encryption/aes192-cbc.pskcxml,
+ tests/encryption/aes256-cbc.pskcxml,
+ tests/encryption/kw-aes128.pskcxml,
+ tests/encryption/kw-aes192.pskcxml,
+ tests/encryption/kw-aes256.pskcxml,
+ tests/encryption/kw-tripledes.pskcxml,
+ tests/encryption/tripledes-cbc.pskcxml,
+ tests/invalid-encryption.pskcxml,
+ tests/invalid-mac-algorithm.pskcxml,
+ tests/invalid-mac-value.pskcxml,
+ tests/invalid-no-mac-method.pskcxml, tests/invalid-notxml.pskcxml,
+ tests/invalid-wrongelement.pskcxml,
+ tests/invalid-wrongversion.pskcxml,
+ tests/invalid/encryption.pskcxml,
+ tests/invalid/mac-algorithm.pskcxml,
+ tests/invalid/mac-value.pskcxml,
+ tests/invalid/no-mac-method.pskcxml,
+ tests/invalid/notxml.pskcxml, tests/invalid/wrongelement.pskcxml,
+ tests/invalid/wrongversion.pskcxml, tests/kw-aes128.pskcxml,
+ tests/kw-aes192.pskcxml, tests/kw-aes256.pskcxml,
+ tests/kw-tripledes.pskcxml, tests/misc/SampleFullyQualifiedNS.xml,
+ tests/misc/odd-namespace.pskcxml, tests/odd-namespace.pskcxml,
+ tests/rfc6030-figure10.pskcxml, tests/rfc6030-figure2.pskcxml,
+ tests/rfc6030-figure3.pskcxml, tests/rfc6030-figure4.pskcxml,
+ tests/rfc6030-figure5.pskcxml, tests/rfc6030-figure6.pskcxml,
+ tests/rfc6030-figure7.pskcxml, tests/rfc6030/figure10.pskcxml,
+ tests/rfc6030/figure2.pskcxml, tests/rfc6030/figure3.pskcxml,
+ tests/rfc6030/figure4.pskcxml, tests/rfc6030/figure5.pskcxml,
+ tests/rfc6030/figure6.pskcxml, tests/rfc6030/figure7.pskcxml,
+ tests/test_draft_keyprov.doctest, tests/test_encryption.doctest,
+ tests/test_invalid.doctest, tests/test_misc.doctest,
+ tests/test_rfc6030.doctest, tests/test_write.doctest,
+ tests/tripledes-cbc.pskcxml: Re-organise test files
+
+ This puts the test PSKC files in subdirectories so they can be
+ organised more cleanly.
+
+2016-01-23 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [1904dc2] tests/test_misc.doctest: Add test for incorrect key
+ derivation
+
+ If no key derivation algorithm has been specified in the PSKC
+ file an exception should be raised when attempting to perform
+ key derivation.
+
+2016-01-24 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [91f66f4] pskc/encryption.py, pskc/key.py, pskc/mac.py: Refactor
+ out EncryptedValue and ValueMAC
+
+ This removes the EncryptedValue and ValueMAC classes and instead
+ moves the XML parsing of these values to the DataType class. This
+ will make it easier to support different parsing schemes.
+
+ This also includes a small consistency improvement in the
+ subclasses of DataType.
+
+2016-01-23 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [9b13d3b] pskc/encryption.py, tests/test_misc.doctest: Normalise
+ algorithm names
+
+ This transforms the algorithm URIs that are set to known values
+ when parsing or setting the algorithm.
+
+2016-01-22 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [b6eab47] docs/encryption.rst, pskc/encryption.py,
+ tests/test_encryption.doctest, tests/test_misc.doctest: Add
+ encryption algorithm property
+
+ Either determine the encryption algorithm from the PSKC file
+ or from the explicitly set value. This also adds support for
+ setting the encryption key name.
+
+2016-01-22 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [b5f7de5] pskc/key.py, tests/test_write.doctest: Fix a problem
+ when writing previously encrypted file
+
+ This fixes a problem with writing a PSKC file that is based on
+ a read file that was encrypted.
+
+2016-01-22 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [107a836] pskc/__init__.py, pskc/encryption.py, pskc/key.py,
+ pskc/mac.py, pskc/policy.py, pskc/xml.py: Strip XML namespaces
+ before parsing
+
+ This simplifies calls to the find() family of functions and
+ allows parsing PSKC files that have slightly different namespace
+ URLs. This is especially common when parsing old draft versions
+ of the specification.
+
+ This also removes passing multiple patterns to the find()
+ functions that was introduced in 68b20e2.
+
+2015-12-28 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [a86ff8a] README, docs/encryption.rst: Update some documentation
+
+ This adds a development notes section to the README and changes
+ the wording on the encryption page.
+
+2015-12-01 Mathias Laurin <Mathias.Laurin+github.com at gmail.com>
+
+ * [0ff4154] docs/encryption.rst: Fix typo in the documentation
+
+2015-12-01 Mathias Laurin <Mathias.Laurin+github.com at gmail.com>
+
+ * [3473903] pskc2csv.py: Support Python 3
+
+2015-11-30 Mathias Laurin <Mathias.Laurin+github.com at gmail.com>
+
+ * [a82a60b] pskc/key.py: Make value conversion methods static private
+
+ - the conversions do not call self: they are static - the
+ conversions are not to be used out of the class: make private
+
+2015-11-30 Mathias Laurin <Mathias.Laurin+github.com at gmail.com>
+
+ * [e711a30] pskc/key.py: Provide abstract methods to clarify API
+
+2015-11-30 Mathias Laurin <Mathias.Laurin+github.com at gmail.com>
+
+ * [1577687] pskc/encryption.py: Fix typo in variable name
+
+2015-11-30 Mathias Laurin <Mathias.Laurin+github.com at gmail.com>
+
+ * [3aa2a6f] tests/test_invalid.doctest: Fix doctest:
+ IGNORE_EXCEPTION_DETAL
+
+2015-10-07 Arthur de Jong <arthur at arthurdejong.org>
+
+ * [c155d15] ChangeLog, MANIFEST.in, NEWS, pskc/__init__.py,
+ setup.py: Get files ready for 0.3 release
+
2015-10-07 Arthur de Jong <arthur at arthurdejong.org>
* [cf0c9e6] README, docs/conf.py, docs/encryption.rst,
diff --git a/NEWS b/NEWS
index 3200bce..b1b4c1e 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,21 @@
+changes from 0.3 to 0.4
+-----------------------
+
+* add support for writing encrypted PSKC files (with either a pre-shared key
+ or PBKDF2 password-based encryption)
+* extend may_use() policy checking function to check for unknown policy
+ elements and key expiry
+* add a number of tests for existing vendor PSKC files and have full line
+ coverage with tests
+* be more lenient in handling a number of XML files (e.g. automatically
+ sanitise encryption algorithm URIs, ignore XML namespaces and support more
+ spellings of some properties)
+* support reading password or key files in pskc2csv
+* support Python 3 in the pskc2csv script (thanks Mathias Laurin)
+* refactoring and clean-ups to be more easily extendible (thanks Mathias
+ Laurin)
+
+
changes from 0.2 to 0.3
-----------------------
diff --git a/PKG-INFO b/PKG-INFO
index 0b63ca7..f9a15a5 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: python-pskc
-Version: 0.3
+Version: 0.4
Summary: Python module for handling PSKC files
Home-page: http://arthurdejong.org/python-pskc/
Author: Arthur de Jong
@@ -13,13 +13,13 @@ Description: Python module for handling PSKC files
keys (seed files) to different types of crypto modules, commonly one-time
password tokens or other authentication devices.
- The main goal of this module is to be able to extract keys from PSKC files
- for use in an OTP authentication system.
+ This module can be used to extract keys from PSKC files for use in an OTP
+ authentication system. The module can also be used for authoring PSKC files.
The following prints all keys, decrypting using a password:
>>> from pskc import PSKC
- >>> pskc = PSKC('tests/rfc6030-figure7.pskcxml')
+ >>> pskc = PSKC('tests/rfc6030/figure7.pskcxml')
>>> pskc.encryption.derive_key('qwerty')
>>> for key in pskc.keys:
... print('%s %s' % (key.serial, str(key.secret.decode())))
@@ -42,5 +42,7 @@ Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
+Classifier: Topic :: Security :: Cryptography
Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Classifier: Topic :: System :: Systems Administration :: Authentication/Directory
Classifier: Topic :: Text Processing :: Markup :: XML
diff --git a/README b/README
index 7dd7ea0..d52ded3 100644
--- a/README
+++ b/README
@@ -3,12 +3,12 @@ Python PSKC module
A Python module to handle Portable Symmetric Key Container (PSKC) files as
defined in `RFC 6030 <https://tools.ietf.org/html/rfc6030>`_. PSKC files are
-used to transport and provision symmetric keys and key meta data to different
-types of crypto modules. The format is commonly used for one-time password
-tokens or other authentication devices.
+used to transport and provision symmetric keys and key meta data (seed files)
+to different types of crypto modules, commonly 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.
+This module can be used to extract keys from PSKC files for use in an OTP
+authentication system. The module can also be used for authoring PSKC files.
http://arthurdejong.org/python-pskc/
@@ -19,10 +19,10 @@ API
The module provides a straightforward API that is mostly geared towards
parsing existing PSKC files.
-Extracting key matarial from encrypted PSKC files is as simple as.
+Extracting key material from encrypted PSKC files is as simple as.
>>> from pskc import PSKC
->>> pskc = PSKC('tests/rfc6030-figure7.pskcxml')
+>>> pskc = PSKC('tests/rfc6030/figure7.pskcxml')
>>> pskc.encryption.derive_key('qwerty')
>>> for key in pskc.keys:
... print key.serial, key.secret
@@ -44,7 +44,7 @@ private key material.
Copyright
---------
-Copyright (C) 2014-2015 Arthur de Jong
+Copyright (C) 2014-2016 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
@@ -60,3 +60,12 @@ 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
+
+
+Development notes
+-----------------
+
+This package should use a mostly standard source code layout and support both
+Python 2 (2.6 but 2.7 is recommended) and Python 3 (most recent versions
+should work). The tests can be run with nosetests and the aim is to have
+maximum code coverage.
diff --git a/docs/conf.py b/docs/conf.py
index 268d158..5a7ecbf 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-2015 Arthur de Jong'
+copyright = u'2014-2016 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 8b0ed2f..cafdb74 100644
--- a/docs/encryption.rst
+++ b/docs/encryption.rst
@@ -3,15 +3,15 @@ PSKC encryption
.. module:: pskc.encryption
-The keys (and some embedded data) in PSKC files can be encrypted with either
-pre-shared keys, passphrase-based keys or asymmetric keys (asymmetric keys
-are currently unimplemented).
+Some of the information in PSKC files (e.g. key material) can be encrypted
+with either 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 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 binascii import a2b_hex
>>> from pskc import PSKC
>>> pskc = PSKC('somefile.pskcxml')
>>> pskc.encryption.key = a2b_hex('12345678901234567890123456789012')
@@ -23,11 +23,23 @@ or::
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, upon accessing encrypted
+If no key or an incorrect key has been configured, 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.
+When writing out a PSKC file, encryption can be configured with the
+:func:`~pskc.encryption.Encryption.setup_preshared_key()` or
+:func:`~pskc.encryption.Encryption.setup_pbkdf2()` function::
+
+ >>> from pskc import PSKC
+ >>> pskc = PSKC()
+ >>> pskc.encryption.setup_preshared_key(algorithm='AES256-CBC')
+
+or::
+
+ >>> pskc.encryption.setup_pbkdf2(password='verysecure')
+
The Encryption class
--------------------
@@ -38,6 +50,13 @@ The Encryption class
Optional identifier of the encryption key.
+ .. attribute:: algorithm
+
+ A URI of the encryption algorithm used. Setting a value for this
+ attribute will result in an attempt to use the canonical URI for this
+ algorithm. For instance setting a `3DES-CBC` value will automatically
+ be converted to `http://www.w3.org/2001/04/xmlenc#aes128-cbc`.
+
.. attribute:: key_names
List of names provided for the encryption key.
@@ -46,7 +65,7 @@ The Encryption class
Since usually only one name is defined for a key but the schema allows
for multiple names, this is a shortcut for accessing the first value of
- :attr:`key_names`.
+ :attr:`key_names`. It will return ``None`` if no name is available.
.. attribute:: key
@@ -64,3 +83,58 @@ The Encryption class
This function may raise a :exc:`~pskc.exceptions.KeyDerivationError`
exception if key derivation fails for some reason.
+
+ .. attribute:: fields
+
+ A list of :class:`~pskc.key.Key` instance field names that will be
+ encrypted when the PSKC file is written. List values can contain
+ ``secret``, ``counter``, ``time_offset``, ``time_interval`` and
+ ``time_drift``.
+
+ .. function:: setup_preshared_key(...)
+
+ Configure pre-shared key encryption.
+
+ :param binary key: the encryption key to use
+ :param str id: encryption key identifier
+ :param str algorithm: encryption algorithm
+ :param int key_length: encryption key length in bytes
+ :param str key_name: a name for the key
+ :param list key_names: a number of names for the key
+ :param list fields: a list of fields to encrypt
+
+ This is a utility function to easily set up encryption. Encryption can
+ also be set up by manually by setting the
+ :class:`~pskc.encryption.Encryption` properties.
+
+ This method will generate a key if required and set the passed values.
+ By default AES128-CBC encryption will be configured and unless a key is
+ specified one of the correct length will be generated. If the algorithm
+ does not provide integrity checks (e.g. CBC-mode algorithms) integrity
+ checking in the PSKC file will be set up using
+ :func:`~pskc.mac.MAC.setup()`.
+
+ By default only the :attr:`~pskc.key.Key.secret` property will be
+ encrypted when writing the file.
+
+ .. function:: setup_pbkdf2(...)
+
+ Configure password-based PSKC encryption.
+
+ :param str password: the password to use (required)
+ :param str id: encryption key identifier
+ :param str algorithm: encryption algorithm
+ :param int key_length: encryption key length in bytes
+ :param str key_name: a name for the key
+ :param list key_names: a number of names for the key
+ :param list fields: a list of fields to encrypt
+ :param binary salt: PBKDF2 salt
+ :param int salt_length: used when generating random salt
+ :param int iterations: number of PBKDF2 iterations
+ :param function prf: PBKDF2 pseudorandom function
+
+ Defaults for the above parameters are similar to those for
+ :func:`setup_preshared_key()` but the password parameter is required.
+
+ By default 12000 iterations will be used and a random salt with the
+ length of the to-be-generated encryption key will be used.
diff --git a/docs/mac.rst b/docs/mac.rst
index 4847071..0e8e5d5 100644
--- a/docs/mac.rst
+++ b/docs/mac.rst
@@ -38,3 +38,14 @@ The MAC class
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`).
+
+ .. function:: setup(...)
+
+ Configure an encrypted MAC key.
+
+ :param str algorithm: encryption algorithm
+ :param binary key: the encryption key to use
+
+ None of the arguments are required. By default HMAC-SHA1 will be used
+ as a MAC algorithm. If no key is configured a random key will be
+ generated with the length of the output of the configured hash.
diff --git a/docs/policy.rst b/docs/policy.rst
index 97f9250..cad018f 100644
--- a/docs/policy.rst
+++ b/docs/policy.rst
@@ -92,11 +92,11 @@ The Policy class
value is ``True`` to ensure that the lack of understanding of certain
extensions does not lead to unintended key usage.
- .. function:: may_use(usage)
-
- Check whether the key may be used for the provided purpose. See
- :ref:`key-use-constants` below.
+ .. function:: may_use(usage=None, now=None)
+ Check whether the key may be used for the provided purpose. The key
+ :attr:`start_date` and :attr:`expiry_date` are also checked. The `now`
+ argument can be used to specify another point in time to check against.
.. _key-use-constants:
diff --git a/docs/usage.rst b/docs/usage.rst
index 7a9cdcb..5e0edfc 100644
--- a/docs/usage.rst
+++ b/docs/usage.rst
@@ -1,13 +1,13 @@
Basic usage
===========
-The :mod:`pskc` module implements a simple and efficient API for parsing PSKC
-files. The :class:`~pskc.PSKC` class is used to access the file as a whole
-which provides access to a list of :class:`~pskc.key.Key` instances which
-contain most of the useful information from the PSKC file.
+The :mod:`pskc` module implements a simple and efficient API for parsing and
+creating PSKC files. The :class:`~pskc.PSKC` class is used to access the file
+as a whole which provides access to a list of :class:`~pskc.key.Key`
+instances which contain most of the useful information of the PSKC file.
-Opening a PSKC file
+Reading a PSKC file
-------------------
Importing data from a PSKC file can be done by instantiating the
@@ -50,16 +50,15 @@ 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'
+ >>> key = pskc.add_key(
+ ... id='456', secret='987654321', manufacturer='Manufacturer',
+ ... 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.
+By default an unencrypted PSKC file will be created but an encryption can be
+configured using the
+:func:`~pskc.encryption.Encryption.setup_preshared_key()` or
+:func:`~pskc.encryption.Encryption.setup_pbkdf2()` function.
The PSKC class
diff --git a/pskc/__init__.py b/pskc/__init__.py
index 685843b..843a919 100644
--- a/pskc/__init__.py
+++ b/pskc/__init__.py
@@ -1,7 +1,7 @@
# __init__.py - main module
# coding: utf-8
#
-# Copyright (C) 2014-2015 Arthur de Jong
+# Copyright (C) 2014-2016 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
@@ -25,13 +25,13 @@ defined in RFC 6030. PSKC files are used to transport and provision symmetric
keys (seed files) to different types of crypto modules, commonly one-time
password tokens or other authentication devices.
-The main goal of this module is to be able to extract keys from PSKC files
-for use in an OTP authentication system.
+This module can be used to extract keys from PSKC files for use in an OTP
+authentication system. The module can also be used for authoring PSKC files.
The following prints all keys, decrypting using a password:
>>> from pskc import PSKC
->>> pskc = PSKC('tests/rfc6030-figure7.pskcxml')
+>>> pskc = PSKC('tests/rfc6030/figure7.pskcxml')
>>> pskc.encryption.derive_key('qwerty')
>>> for key in pskc.keys:
... print('%s %s' % (key.serial, str(key.secret.decode())))
@@ -45,7 +45,7 @@ __all__ = ['PSKC', '__version__']
# the version number of the library
-__version__ = '0.3'
+__version__ = '0.4'
class PSKC(object):
@@ -66,15 +66,16 @@ class PSKC(object):
from pskc.mac import MAC
self.version = None
self.id = None
- self.encryption = Encryption()
+ self.encryption = Encryption(self)
self.mac = MAC(self)
self.keys = []
if filename is not None:
- from pskc.xml import parse
+ from pskc.xml import parse, remove_namespaces
try:
tree = parse(filename)
except Exception:
raise ParseError('Error parsing XML')
+ remove_namespaces(tree)
self.parse(tree.getroot())
else:
self.version = '1.0'
@@ -84,7 +85,7 @@ class PSKC(object):
from pskc.exceptions import ParseError
from pskc.key import Key
from pskc.xml import find, findall
- if not container.tag.endswith('KeyContainer'):
+ if container.tag != 'KeyContainer':
raise ParseError('Missing KeyContainer')
# the version of the PSKC schema
self.version = container.get('Version')
@@ -93,17 +94,19 @@ class PSKC(object):
# unique identifier for the container
self.id = container.get('Id')
# handle EncryptionKey entries
- self.encryption.parse(find(container, 'pskc:EncryptionKey'))
+ self.encryption.parse(find(container, 'EncryptionKey'))
# handle MACMethod entries
- self.mac.parse(find(container, 'pskc:MACMethod'))
+ self.mac.parse(find(container, 'MACMethod'))
# handle KeyPackage entries
- for key_package in findall(container, 'pskc:KeyPackage'):
+ for key_package in findall(container, '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)
+ self.encryption.make_xml(container)
+ self.mac.make_xml(container)
for key in self.keys:
key.make_xml(container)
return container
@@ -127,7 +130,12 @@ class PSKC(object):
"""Write the PSKC file to the provided file."""
from pskc.xml import tostring
if hasattr(filename, 'write'):
- filename.write(tostring(self.make_xml()))
+ xml = tostring(self.make_xml())
+ try:
+ filename.write(xml)
+ except TypeError: # pragma: no cover (Python 3 specific)
+ # fall back to writing as string for Python 3
+ filename.write(xml.decode('utf-8'))
else:
with open(filename, 'wb') as output:
self.write(output)
diff --git a/pskc/encryption.py b/pskc/encryption.py
index 4911662..5a476c1 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-2015 Arthur de Jong
+# Copyright (C) 2014-2016 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,92 +20,74 @@
"""Module that handles encrypted PSKC values.
-This module defines an Encryption class that handles the encryption key
-and an EncryptedValue wrapper class that can decrypt values using the
-encryption key.
+This module defines an Encryption class that handles the encryption key,
+algorithms and decryption.
The encryption key can be derived using the KeyDerivation class.
"""
+import base64
-def unpad(value):
- """Remove padding from the plaintext."""
- return value[0:-ord(value[-1:])]
+# cannonical URIs of known algorithms
+_algorithms = {
+ 'tripledes-cbc': 'http://www.w3.org/2001/04/xmlenc#tripledes-cbc',
+ 'kw-tripledes': 'http://www.w3.org/2001/04/xmlenc#kw-tripledes',
+ 'aes128-cbc': 'http://www.w3.org/2001/04/xmlenc#aes128-cbc',
+ 'aes192-cbc': 'http://www.w3.org/2001/04/xmlenc#aes192-cbc',
+ 'aes256-cbc': 'http://www.w3.org/2001/04/xmlenc#aes256-cbc',
+ 'kw-aes128': 'http://www.w3.org/2001/04/xmlenc#kw-aes128',
+ 'kw-aes192': 'http://www.w3.org/2001/04/xmlenc#kw-aes192',
+ 'kw-aes256': 'http://www.w3.org/2001/04/xmlenc#kw-aes256',
+ 'camellia128': 'http://www.w3.org/2001/04/xmldsig-more#camellia128',
+ 'camellia192': 'http://www.w3.org/2001/04/xmldsig-more#camellia192',
+ 'camellia256': 'http://www.w3.org/2001/04/xmldsig-more#camellia256',
+ 'kw-camellia128': 'http://www.w3.org/2001/04/xmldsig-more#kw-camellia128',
+ 'kw-camellia192': 'http://www.w3.org/2001/04/xmldsig-more#kw-camellia192',
+ 'kw-camellia256': 'http://www.w3.org/2001/04/xmldsig-more#kw-camellia256',
+ 'hmac-md5': 'http://www.w3.org/2001/04/xmldsig-more#hmac-md5',
+ 'hmac-sha1': 'http://www.w3.org/2000/09/xmldsig#hmac-sha1',
+ 'hmac-sha224': 'http://www.w3.org/2001/04/xmldsig-more#hmac-sha224',
+ 'hmac-sha256': 'http://www.w3.org/2001/04/xmldsig-more#hmac-sha256',
+ 'hmac-sha384': 'http://www.w3.org/2001/04/xmldsig-more#hmac-sha384',
+ 'hmac-sha512': 'http://www.w3.org/2001/04/xmldsig-more#hmac-sha512',
+ 'hmac-ripemd160': 'http://www.w3.org/2001/04/xmldsig-more#hmac-ripemd160',
+ 'pbkdf2': 'http://www.rsasecurity.com/rsalabs/pkcs/schemas/' +
+ 'pkcs-5v2-0#pbkdf2',
+}
+# translation table to change old encryption names to new names
+_algorithm_aliases = {
+ '3des-cbc': 'tripledes-cbc',
+ '3des112-cbc': 'tripledes-cbc',
+ '3des168-cbc': 'tripledes-cbc',
+ 'kw-3des': 'kw-tripledes',
+ 'pbe-3des112-cbc': 'tripledes-cbc',
+ 'pbe-3des168-cbc': 'tripledes-cbc',
+ 'pbe-aes128-cbc': 'aes128-cbc',
+ 'pbe-aes192-cbc': 'aes192-cbc',
+ 'pbe-aes256-cbc': 'aes256-cbc',
+ 'rsa-1_5': 'rsa-1_5',
+ 'rsa-oaep-mgf1p': 'rsa-oaep-mgf1p',
+}
-class EncryptedValue(object):
- """Wrapper class to handle encrypted values.
- Instances of this class provide the following attributes:
+def normalise_algorithm(algorithm):
+ """Return the canonical URI for the provided algorithm."""
+ if not algorithm or algorithm.lower() == 'none':
+ return None
+ algorithm = _algorithm_aliases.get(algorithm.lower(), algorithm)
+ return _algorithms.get(algorithm.rsplit('#', 1)[-1].lower(), algorithm)
- algorithm: name of the encryption algorithm used
- cipher_value: binary encrypted data
- """
- def __init__(self, encryption, encrypted_value=None):
- """Initialise an encrypted value for the provided Key."""
- self.encryption = encryption
- self.algorithm = None
- self.cipher_value = None
- self.parse(encrypted_value)
+def pad(value, block_size):
+ """Pad the value to block_size length."""
+ padding = block_size - (len(value) % block_size)
+ return value + padding * chr(padding).encode('ascii')
- def parse(self, encrypted_value):
- """Read encrypted data from the <EncryptedValue> XML tree."""
- from pskc.xml import find, findbin
- if encrypted_value is None:
- return
- encryption_method = find(encrypted_value, 'xenc:EncryptionMethod')
- if encryption_method is not None:
- self.algorithm = encryption_method.attrib.get('Algorithm')
... 3541 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