python-pskc branch master updated. 1.0-10-gb3e7fe7
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
python-pskc branch master updated. 1.0-10-gb3e7fe7
- From: Commits of the python-pskc project <python-pskc-commits [at] lists.arthurdejong.org>
- To: python-pskc-commits [at] lists.arthurdejong.org
- Reply-to: python-pskc-users [at] lists.arthurdejong.org
- Subject: python-pskc branch master updated. 1.0-10-gb3e7fe7
- Date: Thu, 15 Feb 2018 18:50:59 +0100 (CET)
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "python-pskc".
The branch, master has been updated
via b3e7fe7b513ced378600b7fa08a96779e54e2b4e (commit)
from 03ee35d2ce72cb4d84c6f01bd699321aff92d4cf (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
https://arthurdejong.org/git/python-pskc/commit/?id=b3e7fe7b513ced378600b7fa08a96779e54e2b4e
commit b3e7fe7b513ced378600b7fa08a96779e54e2b4e
Author: Arthur de Jong <arthur@arthurdejong.org>
Date: Thu Feb 15 18:46:14 2018 +0100
Add and cleanup docstrings
This adds docstrings to public methods and cleans up a few other
docstrings to pass most flake8 docstring related tests.
This also adds noqa statements in a few places so we can remove most
entries from the global flake8 ignore list.
diff --git a/pskc/__init__.py b/pskc/__init__.py
index 91c6f71..d2e8868 100644
--- a/pskc/__init__.py
+++ b/pskc/__init__.py
@@ -18,7 +18,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA
-"""Python module for handling PSKC files
+"""Python module for handling PSKC files.
This Python library handles Portable Symmetric Key Container (PSKC) files as
defined in RFC 6030. PSKC files are used to transport and provision symmetric
@@ -95,7 +95,8 @@ class PSKC(object):
"""Create a new device instance for the PSKC file.
The device is initialised with properties from the provided keyword
- arguments if any."""
+ arguments if any.
+ """
from pskc.device import Device
device = Device(self)
self.devices.append(device)
@@ -110,7 +111,8 @@ class PSKC(object):
"""Create a new key instance for the PSKC file.
The new key is initialised with properties from the provided keyword
- arguments if any."""
+ arguments if any.
+ """
device = self.add_device()
key = device.add_key()
# assign the kwargs as key properties
diff --git a/pskc/crypto/aeskw.py b/pskc/crypto/aeskw.py
index a3e2188..b141aad 100644
--- a/pskc/crypto/aeskw.py
+++ b/pskc/crypto/aeskw.py
@@ -54,8 +54,8 @@ def wrap(plaintext, key, iv=None, pad=None,
algorithm=algorithms.AES):
If pad is True, padding as described in RFC 5649 will always be used. If
pad is False, padding is disabled. Other values automatically enable RFC
- 5649 padding when needed."""
-
+ 5649 padding when needed.
+ """
if iv is not None:
pad = False
@@ -80,13 +80,13 @@ def wrap(plaintext, key, iv=None, pad=None,
algorithm=algorithms.AES):
# RFC 5649 shortcut
return encryptor.update(iv + plaintext)
- A = iv
- R = [plaintext[i * 8:i * 8 + 8]
+ A = iv # noqa: N806
+ R = [plaintext[i * 8:i * 8 + 8] # noqa: N806
for i in range(n)]
for j in range(6):
for i in range(n):
A, R[i] = _split(encryptor.update(A + R[i]))
- A = _strxor(A, struct.pack('>Q', n * j + i + 1))
+ A = _strxor(A, struct.pack('>Q', n * j + i + 1)) # noqa: N806
return A + b''.join(R)
@@ -97,8 +97,8 @@ def unwrap(ciphertext, key, iv=None, pad=None,
algorithm=algorithms.AES):
RFC 5649 will be used, depending on the value of pad.
If pad is False, unpadding as described in RFC 5649 will be disabled,
- otherwise checking and removing the padding is automatically done."""
-
+ otherwise checking and removing the padding is automatically done.
+ """
if iv is not None:
pad = False
@@ -112,12 +112,12 @@ def unwrap(ciphertext, key, iv=None, pad=None,
algorithm=algorithms.AES):
if n == 1:
A, plaintext = _split(decryptor.update(ciphertext))
else:
- A = ciphertext[:8]
- R = [ciphertext[(i + 1) * 8:(i + 2) * 8]
+ A = ciphertext[:8] # noqa: N806
+ R = [ciphertext[(i + 1) * 8:(i + 2) * 8] # noqa: N806
for i in range(n)]
for j in reversed(range(6)):
for i in reversed(range(n)):
- A = _strxor(A, struct.pack('>Q', n * j + i + 1))
+ A = _strxor(A, struct.pack('>Q', n * j + i + 1)) # noqa: N806
A, R[i] = _split(decryptor.update(A + R[i]))
plaintext = b''.join(R)
diff --git a/pskc/device.py b/pskc/device.py
index 6eac716..ec2eb64 100644
--- a/pskc/device.py
+++ b/pskc/device.py
@@ -57,7 +57,8 @@ class Device(object):
"""Create a new key instance for the device.
The new key is initialised with properties from the provided keyword
- arguments if any."""
+ arguments if any.
+ """
from pskc.key import Key
key = Key(self)
self.keys.append(key)
diff --git a/pskc/encryption.py b/pskc/encryption.py
index e1f56c9..7c23c5e 100644
--- a/pskc/encryption.py
+++ b/pskc/encryption.py
@@ -211,6 +211,7 @@ class KeyDerivation(object):
self._pbkdf2_prf = normalise_algorithm(value)
def derive_pbkdf2(self, password):
+ """Derive an encryption key from the provided password."""
from hashlib import pbkdf2_hmac
from pskc.exceptions import KeyDerivationError
prf = 'sha1'
@@ -249,6 +250,7 @@ class KeyDerivation(object):
def setup_pbkdf2(self, password, salt=None, salt_length=16,
key_length=None, iterations=None, prf=None):
+ """Configure PBKDF2 key derivation properties."""
self.algorithm = 'pbkdf2'
if salt is None:
salt = os.urandom(salt_length)
diff --git a/pskc/key.py b/pskc/key.py
index b1ede98..00cfad2 100644
--- a/pskc/key.py
+++ b/pskc/key.py
@@ -1,7 +1,7 @@
# key.py - module for handling keys from pskc files
# coding: utf-8
#
-# Copyright (C) 2014-2017 Arthur de Jong
+# Copyright (C) 2014-2018 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
@@ -37,6 +37,7 @@ class EncryptedValue(object):
@classmethod
def create(cls, pskc, value):
+ """Construct an encryped value from a plaintext value."""
# force conversion to bytestring on Python 3
if not isinstance(value, type(b'')):
value = value.encode() # pragma: no cover (Python 3 specific)
@@ -62,9 +63,11 @@ class EncryptedValue(object):
class EncryptedIntegerValue(EncryptedValue):
+ """Class representing an encrypted integer value."""
@classmethod
def create(cls, pskc, value):
+ """Construct an encryped value from a plaintext value."""
value = '%x' % value
n = len(value)
value = binascii.unhexlify(value.zfill(n + (n & 1)))
diff --git a/pskc/parser.py b/pskc/parser.py
index b3e7952..f9c9567 100644
--- a/pskc/parser.py
+++ b/pskc/parser.py
@@ -1,7 +1,7 @@
# parser.py - PSKC file parsing functions
# coding: utf-8
#
-# Copyright (C) 2016-2017 Arthur de Jong
+# Copyright (C) 2016-2018 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
@@ -52,11 +52,11 @@ def plain2int(value):
class PSKCParser(object):
+ """Class to read various PSKC XML files into a PSKC structure."""
@classmethod
def parse_file(cls, pskc, filename):
- """Parse the provided file and store information in the existing
- PSKC instance."""
+ """Parse the provided file and store data in the PSKC instance."""
try:
tree = parse(filename)
except Exception:
@@ -163,7 +163,7 @@ class PSKCParser(object):
@classmethod
def parse_key_package(cls, device, key_package):
"""Read key information from the provided <KeyPackage> tree."""
-
+ # find basic device information
info = find(key_package, 'DeviceInfo', 'DeviceId')
if info is not None:
device.manufacturer = findtext(info, 'Manufacturer')
@@ -174,23 +174,23 @@ class PSKCParser(object):
device.start_date = findtime(info, 'StartDate')
device.expiry_date = findtime(info, 'ExpiryDate', 'Expiry')
device.device_userid = findtext(info, 'UserId')
-
+ # find crypto module info
device.crypto_module = findtext(key_package, 'CryptoModuleInfo/Id')
-
+ # find keys for device
for key_elm in findall(key_package, 'Key', 'Secret'):
cls.parse_key(device.add_key(), key_elm)
@classmethod
def parse_key(cls, key, key_elm):
"""Read key information from the provided <KeyPackage> tree."""
-
+ # get key basic information
key.id = (
key_elm.get('Id') or key_elm.get('KeyId') or
key_elm.get('SecretId'))
key.algorithm = (
key_elm.get('Algorithm') or key_elm.get('KeyAlgorithm') or
key_elm.get('SecretAlgorithm'))
-
+ # parse data section with possibly encrypted data
data = find(key_elm, 'Data')
if data is not None:
cls.parse_data(key, 'secret', find(data, 'Secret'))
@@ -198,7 +198,7 @@ class PSKCParser(object):
cls.parse_data(key, 'time_offset', find(data, 'Time'))
cls.parse_data(key, 'time_interval', find(data, 'TimeInterval'))
cls.parse_data(key, 'time_drift', find(data, 'TimeDrift'))
-
+ # parse legacy data elements with name attribute
for data in findall(key_elm, 'Data'):
name = data.get('Name')
if name:
@@ -208,17 +208,16 @@ class PSKCParser(object):
time='time_offset',
time_interval='time_interval',
).get(name.lower()), data)
-
+ # parse more basic key properties
key.issuer = findtext(key_elm, 'Issuer')
key.key_profile = findtext(key_elm, 'KeyProfileId')
key.key_reference = findtext(key_elm, 'KeyReference')
key.friendly_name = findtext(key_elm, 'FriendlyName')
# TODO: support multi-language values of <FriendlyName>
key.key_userid = findtext(key_elm, 'UserId')
-
key.algorithm_suite = findtext(
key_elm, 'AlgorithmParameters/Suite')
-
+ # parse challenge format
challenge_format = find(
key_elm,
'AlgorithmParameters/ChallengeFormat', 'Usage/ChallengeFormat')
@@ -236,7 +235,7 @@ class PSKCParser(object):
key.challenge_check = getbool(
challenge_format, 'CheckDigits', getbool(
challenge_format, 'CheckDigit'))
-
+ # parse response format
response_format = find(
key_elm,
'AlgorithmParameters/ResponseFormat', 'Usage/ResponseFormat')
@@ -251,9 +250,9 @@ class PSKCParser(object):
key.response_check = getbool(
response_format, 'CheckDigits', getbool(
response_format, 'CheckDigit'))
-
+ # parse key policy information
cls.parse_policy(key.policy, find(key_elm, 'Policy'))
-
+ # parse key usage information
usage = find(key_elm, 'Usage')
if usage is not None:
for att in ('OTP', 'CR', 'Integrity', 'Encrypt', 'Unlock'):
@@ -284,7 +283,8 @@ class PSKCParser(object):
The element is expected to contain <PlainValue>, <EncryptedValue>
and/or <ValueMAC> elements that contain information on the actual
- value."""
+ value.
+ """
if element is None:
return
pskc = key.device.pskc
diff --git a/pskc/serialiser.py b/pskc/serialiser.py
index 26bf1c2..beba1f4 100644
--- a/pskc/serialiser.py
+++ b/pskc/serialiser.py
@@ -35,9 +35,11 @@ def my_b64encode(value):
class PSKCSerialiser(object):
+ """Class for serialising a PSKC structure to PSKC 1.0 XML."""
@classmethod
def serialise_file(cls, pskc, output):
+ """Write the PSKC structure to the specified output file."""
xml = tostring(cls.serialise_document(pskc))
try:
output.write(xml)
@@ -47,6 +49,7 @@ class PSKCSerialiser(object):
@classmethod
def serialise_document(cls, pskc):
+ """Convert the PSKC structure to an element tree structure."""
container = mk_elem('pskc:KeyContainer', Version='1.0', Id=pskc.id)
cls.serialise_encryption(pskc.encryption, container)
cls.serialise_mac(pskc.mac, container)
@@ -56,6 +59,7 @@ class PSKCSerialiser(object):
@classmethod
def serialise_encryption(cls, encryption, container):
+ """Provide an XML element tree for the encryption information."""
if all(x is None
for x in (encryption.id, encryption.key_name, encryption.key,
encryption.derivation.algorithm)):
@@ -71,6 +75,7 @@ class PSKCSerialiser(object):
@classmethod
def serialise_key_derivation(cls, derivation, encryption_key, key_names):
+ """Provide an XML structure for the key derivation properties."""
derived_key = mk_elem(encryption_key, 'xenc11:DerivedKey', empty=True)
key_derivation = mk_elem(derived_key, 'xenc11:KeyDerivationMethod',
Algorithm=derivation.algorithm)
@@ -90,6 +95,7 @@ class PSKCSerialiser(object):
@classmethod
def serialise_mac(cls, mac, container):
+ """Provide an XML structure for the encrypted MAC key."""
key_value = getattr(mac, '_key', None) or mac.pskc.encryption.key
if not mac.algorithm and not key_value:
return
@@ -113,6 +119,7 @@ class PSKCSerialiser(object):
@classmethod
def serialise_key_package(cls, device, container):
+ """Provide an XML structure for key package."""
key_package = mk_elem(container, 'pskc:KeyPackage', empty=True)
if any(x is not None
for x in (device.manufacturer, device.serial, device.model,
@@ -137,6 +144,7 @@ class PSKCSerialiser(object):
@classmethod
def serialise_key(cls, key, key_package):
+ """Provide an XML structure for the key information."""
key_elm = mk_elem(key_package, 'pskc:Key', empty=True, Id=key.id,
Algorithm=key.algorithm)
mk_elem(key_elm, 'pskc:Issuer', key.issuer)
@@ -172,6 +180,7 @@ class PSKCSerialiser(object):
@classmethod
def serialise_data(cls, key, field, key_elm, tag):
+ """Provide an XML structure for the key material."""
value = getattr(key, '_%s' % field, None)
pskc = key.device.pskc
# skip empty values
@@ -217,6 +226,7 @@ class PSKCSerialiser(object):
@classmethod
def serialise_policy(cls, policy, key_elm):
+ """Provide an XML structure with the key policy information."""
# check if any policy attribute is set
if not policy.key_usage and all(x is None for x in (
policy.start_date, policy.expiry_date,
@@ -242,6 +252,7 @@ class PSKCSerialiser(object):
@classmethod
def serialise_signature(cls, signature, container):
+ """Provide an XML structure for embedded XML signature."""
if not signature.key:
return container
# move the namespace to the root element and reformat before signing
diff --git a/pskc/signature.py b/pskc/signature.py
index 601fc48..90c946b 100644
--- a/pskc/signature.py
+++ b/pskc/signature.py
@@ -1,7 +1,7 @@
# signature.py - module for handling signed XML files
# coding: utf-8
#
-# Copyright (C) 2017 Arthur de Jong
+# Copyright (C) 2017-2018 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
@@ -88,8 +88,11 @@ class Signature(object):
@property
def is_signed(self):
- """Test whether the PSKC file contains a signature (not whether the
- signature is valid)."""
+ """Test whether the PSKC file contains a signature.
+
+ This method does not check whether the signature is valid but only if
+ one was present in the PSKC file.
+ """
return bool(
self.algorithm or self.canonicalization_method or
self.digest_algorithm or self.issuer or self.certificate)
@@ -114,9 +117,11 @@ class Signature(object):
def verify(self, certificate=None, ca_pem_file=None):
"""Check that the signature was made with the specified certificate.
+
If no certificate is provided the signature is expected to contain a
signature that is signed by the CA certificate (or the CA standard CA
- certificates when ca_pem_file is absent)."""
+ certificates when ca_pem_file is absent).
+ """
from pskc import PSKC
from pskc.parser import PSKCParser
signed_xml = verify_x509(self.tree, certificate, ca_pem_file)
diff --git a/setup.cfg b/setup.cfg
index 56f0c04..a0725b3 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -20,6 +20,8 @@ all_files = 1
builder = html man
[flake8]
-ignore = D101,D102,D105,D107,D202,D205,D209,D400,N806
+ignore =
+ D105 # Missing docstring in magic method
+ D107 # Missing docstring in __init__
max-complexity = 14
max-line-length = 78
-----------------------------------------------------------------------
Summary of changes:
pskc/__init__.py | 8 +++++---
pskc/crypto/aeskw.py | 20 ++++++++++----------
pskc/device.py | 3 ++-
pskc/encryption.py | 2 ++
pskc/key.py | 5 ++++-
pskc/parser.py | 32 ++++++++++++++++----------------
pskc/serialiser.py | 11 +++++++++++
pskc/signature.py | 13 +++++++++----
setup.cfg | 4 +++-
9 files changed, 62 insertions(+), 36 deletions(-)
hooks/post-receive
--
python-pskc
--
To unsubscribe send an email to
python-pskc-commits-unsubscribe@lists.arthurdejong.org or see
https://lists.arthurdejong.org/python-pskc-commits/
- python-pskc branch master updated. 1.0-10-gb3e7fe7,
Commits of the python-pskc project