Commit 3a94d054 authored by Arthur de Jong's avatar Arthur de Jong

Import python-pskc_0.5.orig.tar.gz

parent 816c2f20
This diff is collapsed.
changes from 0.4 to 0.5
-----------------------
* numerous compatibility improvements for reading PSKC files that do not
follow the RFC 6030 schema exactly: specifically accept a number of old
Internet Draft specifications that preceded RFC 6030 and support an
ActivIdentity file format
* split device information from key information (keep old API available) to
allow multiple keys per device (this is not allowed by RFC 6030 but was
allowed in older Internet Drafts)
* accept MAC to be over plaintext in addition to ciphertext
* fall back to using encryption key as MAC key
* refactoring of some encryption, parsing and serialising functionality into
separate modules for better maintainability
* add configuration for running test suite via Tox
* addition of a large number of test cases, bringing the branch coverage to
100%
* documentation improvements
* drop official support for Python 2.6 (the module still works but is just no
longer tested with it)
changes from 0.3 to 0.4 changes from 0.3 to 0.4
----------------------- -----------------------
......
Metadata-Version: 1.1 Metadata-Version: 1.1
Name: python-pskc Name: python-pskc
Version: 0.4 Version: 0.5
Summary: Python module for handling PSKC files Summary: Python module for handling PSKC files
Home-page: http://arthurdejong.org/python-pskc/ Home-page: http://arthurdejong.org/python-pskc/
Author: Arthur de Jong Author: Arthur de Jong
...@@ -25,6 +25,15 @@ Description: Python module for handling PSKC files ...@@ -25,6 +25,15 @@ Description: Python module for handling PSKC files
... print('%s %s' % (key.serial, str(key.secret.decode()))) ... print('%s %s' % (key.serial, str(key.secret.decode())))
987654321 12345678901234567890 987654321 12345678901234567890
The following generates an encrypted PSKC file:
>>> pskc = PSKC()
>>> key = pskc.add_key(
... id='456', secret='987654321', manufacturer='Manufacturer',
... algorithm = 'urn:ietf:params:xml:ns:keyprov:pskc:hotp')
>>> pskc.encryption.setup_pbkdf2('passphrase')
>>> pskc.write('output.pskcxml')
The module should be able to handle most common PSKC files. The module should be able to handle most common PSKC files.
Keywords: PSKC,RFC 6030,key container Keywords: PSKC,RFC 6030,key container
...@@ -37,11 +46,11 @@ Classifier: License :: OSI Approved :: GNU Lesser General Public License v2 or l ...@@ -37,11 +46,11 @@ Classifier: License :: OSI Approved :: GNU Lesser General Public License v2 or l
Classifier: Operating System :: OS Independent Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Topic :: Security :: Cryptography Classifier: Topic :: Security :: Cryptography
Classifier: Topic :: Software Development :: Libraries :: Python Modules Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Systems Administration :: Authentication/Directory Classifier: Topic :: System :: Systems Administration :: Authentication/Directory
......
...@@ -19,7 +19,7 @@ API ...@@ -19,7 +19,7 @@ API
The module provides a straightforward API that is mostly geared towards The module provides a straightforward API that is mostly geared towards
parsing existing PSKC files. parsing existing PSKC files.
Extracting key material from encrypted PSKC files is as simple as. Extracting key material from encrypted PSKC files is as simple as:
>>> from pskc import PSKC >>> from pskc import PSKC
>>> pskc = PSKC('tests/rfc6030/figure7.pskcxml') >>> pskc = PSKC('tests/rfc6030/figure7.pskcxml')
...@@ -28,6 +28,15 @@ Extracting key material from encrypted PSKC files is as simple as. ...@@ -28,6 +28,15 @@ Extracting key material from encrypted PSKC files is as simple as.
... print key.serial, key.secret ... print key.serial, key.secret
987654321 12345678901234567890 987654321 12345678901234567890
Writing am encrypted PSKC file is as simple as:
>>> pskc = PSKC()
>>> key = pskc.add_key(
... id='456', secret='987654321', manufacturer='Manufacturer',
... algorithm = 'urn:ietf:params:xml:ns:keyprov:pskc:hotp')
>>> pskc.encryption.setup_pbkdf2('passphrase')
>>> pskc.write('output.pskcxml')
The key object has a number of properties. See the pskc.key.Key documentation The key object has a number of properties. See the pskc.key.Key documentation
for details. for details.
...@@ -44,7 +53,7 @@ private key material. ...@@ -44,7 +53,7 @@ private key material.
Copyright Copyright
--------- ---------
Copyright (C) 2014-2016 Arthur de Jong Copyright (C) 2014-2017 Arthur de Jong
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
......
...@@ -46,7 +46,7 @@ master_doc = 'index' ...@@ -46,7 +46,7 @@ master_doc = 'index'
# General information about the project. # General information about the project.
project = u'python-pskc' project = u'python-pskc'
copyright = u'2014-2016 Arthur de Jong' copyright = u'2014-2017 Arthur de Jong'
# The version info for the project you're documenting, acts as replacement for # The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the # |version| and |release|, also used in various other places throughout the
......
...@@ -93,7 +93,7 @@ The Encryption class ...@@ -93,7 +93,7 @@ The Encryption class
.. function:: setup_preshared_key(...) .. function:: setup_preshared_key(...)
Configure pre-shared key encryption. Configure pre-shared key encryption when writing the file.
:param binary key: the encryption key to use :param binary key: the encryption key to use
:param str id: encryption key identifier :param str id: encryption key identifier
...@@ -119,7 +119,7 @@ The Encryption class ...@@ -119,7 +119,7 @@ The Encryption class
.. function:: setup_pbkdf2(...) .. function:: setup_pbkdf2(...)
Configure password-based PSKC encryption. Configure password-based PSKC encryption when writing the file.
:param str password: the password to use (required) :param str password: the password to use (required)
:param str id: encryption key identifier :param str id: encryption key identifier
......
...@@ -3,8 +3,9 @@ Basic usage ...@@ -3,8 +3,9 @@ Basic usage
The :mod:`pskc` module implements a simple and efficient API for parsing and 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 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` as a whole which provides access to a list of :class:`~pskc.device.Device`
instances which contain most of the useful information of the PSKC file. and :class:`~pskc.key.Key` instances which contain most of the useful
information of the PSKC file.
Reading a PSKC file Reading a PSKC file
...@@ -89,6 +90,11 @@ The PSKC class ...@@ -89,6 +90,11 @@ The PSKC class
A unique identifier for the container. A unique identifier for the container.
.. attribute:: devices
A list of :class:`~pskc.device.Device` instances that represent the key
containers within the PSKC file.
.. attribute:: keys .. attribute:: keys
A list of :class:`~pskc.key.Key` instances that represent the keys A list of :class:`~pskc.key.Key` instances that represent the keys
...@@ -105,11 +111,18 @@ The PSKC class ...@@ -105,11 +111,18 @@ The PSKC class
See :doc:`mac` for more information. See :doc:`mac` for more information.
.. function:: add_device([**kwargs])
Add a new key package to the PSKC instance. The keyword arguments may
refer to any attributes of the :class:`~pskc.device.Device` class with
which the new device is initialised.
.. function:: add_key([**kwargs]) .. function:: add_key([**kwargs])
Add a new key to the PSKC instance. The keyword arguments may refer to Add a new key to the PSKC instance. The keyword arguments may refer to
any attributes of the :class:`~pskc.key.Key` class with which the new any attributes of the :class:`~pskc.key.Key` or
key is initialised. :class:`~pskc.device.Device` class with which the new key is
initialised.
.. function:: write(filename) .. function:: write(filename)
...@@ -186,7 +199,7 @@ The Key class ...@@ -186,7 +199,7 @@ The Key class
.. attribute:: issuer .. attribute:: issuer
The name of the party that issued the key. This may be different from The name of the party that issued the key. This may be different from
the :attr:`manufacturer` of the device. the :attr:`~pskc.device.Device.manufacturer` of the device.
.. attribute:: key_profile .. attribute:: key_profile
...@@ -208,62 +221,7 @@ The Key class ...@@ -208,62 +221,7 @@ The Key class
.. attribute:: key_userid .. attribute:: key_userid
The distinguished name of the user associated with the key. The distinguished name of the user associated with the key.
Also see :attr:`device_userid`. Also see :attr:`~pskc.device.Device.device_userid`.
.. attribute:: manufacturer
The name of the manufacturer of the device to which the key is
provisioned.
`RFC 6030 <https://tools.ietf.org/html/rfc6030#section-4.3.1>`__
prescribes that the value is of the form ``oath.prefix`` for `OATH
Manufacturer Prefixes <http://www.openauthentication.org/oath-id/prefixes/>`_
or ``iana.organisation`` for `IANA Private Enterprise Numbers
<https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers>`_
however, it is generally just a string. The value may be different from
the :attr:`issuer` of the key on the device.
.. attribute:: serial
The serial number of the device to which the key is provisioned.
Together with :attr:`manufacturer` (and possibly :attr:`issue_no`) this
should uniquely identify the device.
.. attribute:: model
A manufacturer-specific description of the model of the device.
.. attribute:: issue_no
The issue number in case there are devices with the same :attr:`serial`
number so that they can be distinguished by different issue numbers.
.. attribute:: device_binding
Reference to a device identifier (e.g. IMEI) that allows a provisioning
server to ensure that the key is going to be loaded into a specific
device.
.. attribute:: start_date
:class:`datetime.datetime` value that indicates that the device should
only be used after this date.
.. attribute:: expiry_date
:class:`datetime.datetime` value that indicates that the device should
only be used before this date. Systems should not rely upon the device
to enforce key usage date restrictions, as some devices do not have an
internal clock.
.. attribute:: device_userid
The distinguished name of the user associated with the device.
Also see :attr:`key_userid`.
.. attribute:: crypto_module
Implementation specific unique identifier of the cryptographic module
on the device to which the keys have been (or will be) provisioned.
.. attribute:: algorithm_suite .. attribute:: algorithm_suite
...@@ -322,3 +280,87 @@ The Key class ...@@ -322,3 +280,87 @@ The Key class
This will return None if there is no MAC to be checked. It will return This will return None if there is no MAC to be checked. It will return
True if all the MACs match. If any MAC fails a True if all the MACs match. If any MAC fails a
:exc:`~pskc.exceptions.DecryptionError` exception is raised. :exc:`~pskc.exceptions.DecryptionError` exception is raised.
Apart from the above, all properties of the :class:`~pskc.device.Device`
class are also transparently available in :class:`~pskc.key.Key`
instances.
The Device class
----------------
.. module:: pskc.device
.. class:: Device()
Instances of this class provide the following attributes and functions:
.. attribute:: keys
A list of :class:`~pskc.key.Key` instances that represent the keys that
are linked to this device. Most PSKC files only allow one key per
device which is why all :class:`~pskc.device.Device` attributes are
available in :class:`~pskc.key.Key`.
.. function:: add_key([**kwargs])
Add a new key to the device. The keyword arguments may refer to
any attributes of the :class:`~pskc.key.Key` or
:class:`~pskc.device.Device` class with which the new key is
initialised.
.. attribute:: manufacturer
The name of the manufacturer of the device to which the key is
provisioned.
`RFC 6030 <https://tools.ietf.org/html/rfc6030#section-4.3.1>`__
prescribes that the value is of the form ``oath.prefix`` for `OATH
Manufacturer Prefixes <http://www.openauthentication.org/oath-id/prefixes/>`_
or ``iana.organisation`` for `IANA Private Enterprise Numbers
<https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers>`_
however, it is generally just a string.
The value may be different from the :attr:`~pskc.key.Key.issuer` of
the key on the device.
.. attribute:: serial
The serial number of the device to which the key is provisioned.
Together with :attr:`manufacturer` (and possibly :attr:`issue_no`) this
should uniquely identify the device.
.. attribute:: model
A manufacturer-specific description of the model of the device.
.. attribute:: issue_no
The issue number in case there are devices with the same :attr:`serial`
number so that they can be distinguished by different issue numbers.
.. attribute:: device_binding
Reference to a device identifier (e.g. IMEI) that allows a provisioning
server to ensure that the key is going to be loaded into a specific
device.
.. attribute:: start_date
:class:`datetime.datetime` value that indicates that the device should
only be used after this date.
.. attribute:: expiry_date
:class:`datetime.datetime` value that indicates that the device should
only be used before this date. Systems should not rely upon the device
to enforce key usage date restrictions, as some devices do not have an
internal clock.
.. attribute:: device_userid
The distinguished name of the user associated with the device.
Also see :attr:`~pskc.key.Key.key_userid`.
.. attribute:: crypto_module
Implementation specific unique identifier of the cryptographic module
on the device to which the keys have been (or will be) provisioned.
# __init__.py - main module # __init__.py - main module
# coding: utf-8 # coding: utf-8
# #
# Copyright (C) 2014-2016 Arthur de Jong # Copyright (C) 2014-2017 Arthur de Jong
# #
# This library is free software; you can redistribute it and/or # This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public # modify it under the terms of the GNU Lesser General Public
...@@ -37,6 +37,15 @@ The following prints all keys, decrypting using a password: ...@@ -37,6 +37,15 @@ The following prints all keys, decrypting using a password:
... print('%s %s' % (key.serial, str(key.secret.decode()))) ... print('%s %s' % (key.serial, str(key.secret.decode())))
987654321 12345678901234567890 987654321 12345678901234567890
The following generates an encrypted PSKC file:
>>> pskc = PSKC()
>>> key = pskc.add_key(
... id='456', secret='987654321', manufacturer='Manufacturer',
... algorithm = 'urn:ietf:params:xml:ns:keyprov:pskc:hotp')
>>> pskc.encryption.setup_pbkdf2('passphrase')
>>> pskc.write('output.pskcxml')
The module should be able to handle most common PSKC files. The module should be able to handle most common PSKC files.
""" """
...@@ -45,7 +54,7 @@ __all__ = ['PSKC', '__version__'] ...@@ -45,7 +54,7 @@ __all__ = ['PSKC', '__version__']
# the version number of the library # the version number of the library
__version__ = '0.4' __version__ = '0.5'
class PSKC(object): class PSKC(object):
...@@ -57,68 +66,50 @@ class PSKC(object): ...@@ -57,68 +66,50 @@ class PSKC(object):
id: identifier id: identifier
encryption: information on used encryption (Encryption instance) encryption: information on used encryption (Encryption instance)
mac: information on used MAC method (MAC instance) mac: information on used MAC method (MAC instance)
devices: list of devices (Device instances)
keys: list of keys (Key instances) keys: list of keys (Key instances)
""" """
def __init__(self, filename=None): def __init__(self, filename=None):
from pskc.encryption import Encryption from pskc.encryption import Encryption
from pskc.exceptions import ParseError
from pskc.mac import MAC from pskc.mac import MAC
self.version = None self.version = None
self.id = None self.id = None
self.encryption = Encryption(self) self.encryption = Encryption(self)
self.mac = MAC(self) self.mac = MAC(self)
self.keys = [] self.devices = []
if filename is not None: if filename is not None:
from pskc.xml import parse, remove_namespaces from pskc.parser import PSKCParser
try: PSKCParser.parse_file(self, filename)
tree = parse(filename)
except Exception:
raise ParseError('Error parsing XML')
remove_namespaces(tree)
self.parse(tree.getroot())
else: else:
self.version = '1.0' self.version = '1.0'
def parse(self, container): @property
"""Read information from the provided <KeyContainer> tree.""" def keys(self):
from pskc.exceptions import ParseError return tuple(key for device in self.devices for key in device.keys)
from pskc.key import Key
from pskc.xml import find, findall def add_device(self, **kwargs):
if container.tag != 'KeyContainer': """Create a new device instance for the PSKC file.
raise ParseError('Missing KeyContainer')
# the version of the PSKC schema The device is initialised with properties from the provided keyword
self.version = container.get('Version') arguments if any."""
if self.version != '1.0': from pskc.device import Device
raise ParseError('Unsupported version %r' % self.version) device = Device(self)
# unique identifier for the container self.devices.append(device)
self.id = container.get('Id') # assign the kwargs as key properties
# handle EncryptionKey entries for k, v in kwargs.items():
self.encryption.parse(find(container, 'EncryptionKey')) if not hasattr(device, k):
# handle MACMethod entries raise AttributeError()
self.mac.parse(find(container, 'MACMethod')) setattr(device, k, v)
# handle KeyPackage entries return device
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
def add_key(self, **kwargs): def add_key(self, **kwargs):
"""Create a new key instance for the PSKC file. """Create a new key instance for the PSKC file.
The new key is initialised with properties from the provided keyword The new key is initialised with properties from the provided keyword
arguments if any.""" arguments if any."""
from pskc.key import Key device = self.add_device()
key = Key(self) key = device.add_key()
self.keys.append(key)
# assign the kwargs as key properties # assign the kwargs as key properties
for k, v in kwargs.items(): for k, v in kwargs.items():
if not hasattr(key, k): if not hasattr(key, k):
...@@ -128,14 +119,9 @@ class PSKC(object): ...@@ -128,14 +119,9 @@ class PSKC(object):
def write(self, filename): def write(self, filename):
"""Write the PSKC file to the provided file.""" """Write the PSKC file to the provided file."""
from pskc.xml import tostring from pskc.serialiser import PSKCSerialiser
if hasattr(filename, 'write'): if hasattr(filename, 'write'):
xml = tostring(self.make_xml()) PSKCSerialiser.serialise_file(self, filename)
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: else:
with open(filename, 'wb') as output: with open(filename, 'wb') as output:
self.write(output) self.write(output)
# algorithms.py - module for handling algorithm URIs
# coding: utf-8
#
# Copyright (C) 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
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# 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
"""Utility module that handles algorthm URIs."""
# 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',
}
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)
# __init__.py - general crypto utility functions
# coding: utf-8
#
# Copyright (C) 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
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# 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
"""Implement crypto utility functions."""
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 unpad(value, block_size):
"""Remove padding from the plaintext."""
from pskc.exceptions import DecryptionError
padding = ord(value[-1:])
# only unpad if all padding bytes are the same
if (padding > 0 and padding <= block_size and
value[-padding:] == padding * chr(padding).encode('ascii')):
return value[:-padding]
raise DecryptionError('Invalid padding')
# device.py - module for handling device info from pskc files
# coding: utf-8
#
# Copyright (C) 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
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# 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
"""Module that handles device information stored in PSKC files."""
class Device(object):
"""Representation of a single key from a PSKC file.
Instances of this class provide the following properties:
manufacturer: name of the organisation that made the device
serial: serial number of the device
model: device model description
issue_no: issue number per serial number
device_binding: device (class) identifier for the key to be loaded upon
start_date: key should not be used before this date
expiry_date: key or device may expire after this date
device_userid: user distinguished name associated with the device
crypto_module: id of module to which keys are provisioned within device
"""
def __init__(self, pskc):
self.pskc = pskc
self.manufacturer = None
self.serial = None
self.model = None
self.issue_no = None
self.device_binding = None
self.start_date = None
self.expiry_date = None
self.device_userid = None
self.crypto_module = None
self.keys = []
def add_key(self, **kwargs):
"""Create a new key instance for the device.
The new key is initialised with properties from the provided keyword
arguments if any."""
from pskc.key import Key
key = Key(self)
self.keys.append(key)
# assign the kwargs as key properties
for k, v in kwargs.items():