[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