New Upstream Snapshot - python-rfc3161ng

Ready changes

Summary

Merged new upstream version: 2.1.3+git20201030.1.edb6354 (was: 2.1.1).

Resulting package

Built on 2022-11-14T16:45 (took 10m13s)

The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:

apt install -t fresh-snapshots python3-rfc3161ng

Lintian Result

Diff

diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 731973e..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,105 +0,0 @@
-# Byte-compiled / optimized / DLL files
-__pycache__/
-*.py[cod]
-*$py.class
-
-# C extensions
-*.so
-
-# Distribution / packaging
-.Python
-env/
-build/
-develop-eggs/
-dist/
-downloads/
-eggs/
-.eggs/
-lib/
-lib64/
-parts/
-sdist/
-var/
-wheels/
-*.egg-info/
-.installed.cfg
-*.egg
-
-# PyInstaller
-#  Usually these files are written by a python script from a template
-#  before PyInstaller builds the exe, so as to inject date/other infos into it.
-*.manifest
-*.spec
-
-# Installer logs
-pip-log.txt
-pip-delete-this-directory.txt
-
-# Unit test / coverage reports
-htmlcov/
-.tox/
-.coverage
-.coverage.*
-.cache
-nosetests.xml
-coverage.xml
-*.cover
-.hypothesis/
-
-# Translations
-*.mo
-*.pot
-
-# Django stuff:
-*.log
-local_settings.py
-
-# Flask stuff:
-instance/
-.webassets-cache
-
-# Scrapy stuff:
-.scrapy
-
-# Sphinx documentation
-docs/_build/
-
-# PyBuilder
-target/
-
-# Jupyter Notebook
-.ipynb_checkpoints
-
-# pyenv
-.python-version
-
-# celery beat schedule file
-celerybeat-schedule
-
-# SageMath parsed files
-*.sage.py
-
-# dotenv
-.env
-
-# virtualenv
-.venv
-venv/
-venv3/
-ENV/
-
-# Spyder project settings
-.spyderproject
-.spyproject
-
-# Rope project settings
-.ropeproject
-
-# mkdocs documentation
-/site
-
-# mypy
-.mypy_cache/
-
-# pytest
-.pytest_cache
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index d958470..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-sudo: false
-language: python
-python:
-  - "2.7"
-  - "3.6"
-
-# Enable 3.7 without globally enabling sudo and dist: xenial for other build jobs
-matrix:
-  include:
-    - python: 3.7
-      dist: xenial
-      sudo: true
-install: pip install tox-travis
-script: tox
diff --git a/CHANGELOG b/CHANGELOG
deleted file mode 100644
index 5bc411a..0000000
--- a/CHANGELOG
+++ /dev/null
@@ -1,65 +0,0 @@
-
-Changelog
-=========
-
-2.1.1
------
-
-- Use seconds as argument for tzoffset() for python 2 compatibility
-- Added two more timestamping services in README
-
-
-2.1.0
------
-
-- Fix for #11 Some versions of prettyPrint() include quotes, others do not
-- Add test verify timestamp response with openssl
-- Add test of freetsa.org
-- Add return_tsr option to RemoteTimerstamper object
-- Added License File
-- Updated README
-- ASN.1 generalizedTime to Python datetime parser
-
-
-2.0.4
------
-
-- Add utility functions; make_timestamp_request, encode_timestamp_request,
-    encode_timestamp_response, decode_timestamp_request, decode_timestamp_response
-
-
-2.0.3
------
-
-- Use [bdist_wheel] universal = 1
-
-
-2.0.2
------
-
-- Update example in README.rst
-
-
-2.0.1
------
-
-- Python 3 support
-- Fix certum_certificate.crt
-- Fix style
-- Fix bug(s) with handling requests library and errors from requests
-- Improved API by using exceptions instead of returning error codes
-- Switched to cryptography instead of M2Crypto
-
-
-2.0.0
------
-
-- Fork rfc3161
-
-
-1.0.7
------
-
-- use dateutil to parse genTime
-- fix bad instantiation of UTF8String in PKIFreeText
-- use tox and py.test
diff --git a/PKG-INFO b/PKG-INFO
index 7adf449..a3524bb 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,41 +1,115 @@
-Metadata-Version: 1.0
-Name: rfc3161
-Version: 1.0.7
+Metadata-Version: 2.1
+Name: rfc3161ng
+Version: 2.1.4.dev0
 Summary: Python implementation of the RFC3161 specification, using pyasn1
 Home-page: https://dev.entrouvert.org/projects/python-rfc3161
 Author: Benjamin Dauvergne
 Author-email: bdauvergne@entrouvert.com
+Maintainer: trbs
+Maintainer-email: trbs@trbs.net
 License: MIT
-Description: rfc3161
-        =======
-        
-        A simple client library for cryptographic timestamping service implementing the
-        protocol from RFC3161.
-        
-            >>> import rfc3161
-            >>> certificate = file('data/certum_certificate.crt').read()
-            >>> rt = rfc3161.RemoteTimestamper('http://time.certum.pl', certificate=certificate)
-            >>> rt.timestamp(data='John Doe')
-            ('...', '')
-            >>> rt.check(_, data='John Doe')
-            (True, '')
-            >>> rfc3161.get_timestamp(tst)
-            datetime.datetime(2014, 4, 25, 9, 34, 16)
-        
-        Authors
-        =======
-        
-        Benjamin Dauvergne <bdauvergne@entrouvert.com>
-        Michael Gebetsroither <michael@mgeb.org>
-        
-        Changelog
-        =========
-        
-        1.0.7
-        -----
-        
-        - use dateutil to parse genTime
-        - fix bad instantiation of UTF8String in PKIFreeText
-        - use tox and py.test
-        
-Platform: UNKNOWN
+Platform: any
+Classifier: Environment :: Console
+Classifier: Intended Audience :: Developers
+Classifier: Intended Audience :: Information Technology
+Classifier: Intended Audience :: System Administrators
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Topic :: Communications
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Description-Content-Type: text/x-rst
+License-File: LICENSE
+
+=========
+rfc3161ng
+=========
+
+.. image:: https://img.shields.io/pypi/l/rfc3161ng.svg
+   :target: https://raw.githubusercontent.com/trbs/rfc3161ng/master/LICENSE
+
+.. image:: https://github.com/trbs/rfc3161ng/workflows/CI/badge.svg?branch=master
+     :target: https://github.com/trbs/rfc3161ng/actions?workflow=CI
+     :alt: CI Status
+
+.. image:: https://img.shields.io/pypi/v/rfc3161ng.svg
+    :target: https://pypi.python.org/pypi/rfc3161ng/
+    :alt: Latest PyPI version
+
+.. image:: https://img.shields.io/pypi/wheel/rfc3161ng.svg
+    :target: https://pypi.python.org/pypi/rfc3161ng/
+    :alt: Supports Wheel format
+
+A simple client library for cryptographic timestamping service implementing the
+protocol from RFC3161.
+
+This started as a fork of https://dev.entrouvert.org/projects/python-rfc3161 and
+has some additional patches such as Python3 support.
+
+The latest version of this library is available from
+https://github.com/trbs/rfc3161ng/ .
+
+
+Public providers
+================
+
+There are several timestamping services around.  Here is a list of
+publicly available services you can try:
+
+ * http://freetsa.org/tsr
+ * http://time.certum.pl
+ * http://timestamp.comodoca.com/rfc3161
+ * http://timestamp.geotrust.com/tsa
+ * http://timestamp.globalsign.com/scripts/timstamp.dll
+ * http://tsa.starfieldtech.com
+ * https://teszt.e-szigno.hu:440/tsa
+
+Example
+=======
+
+    >>> import rfc3161ng
+    >>> certificate = open('data/certum_certificate.crt', 'rb').read()
+    >>> rt = rfc3161ng.RemoteTimestamper('http://time.certum.pl', certificate=certificate)
+    >>> tst = rt.timestamp(data=b'John Doe')
+    >>> rt.check(tst, data=b'John Doe')
+    True
+    >>> rfc3161ng.get_timestamp(tst)
+    datetime.datetime(2017, 8, 31, 15, 42, 58, tzinfo=tzutc())
+
+Example for a server that insist on SHA256:
+
+    >> import rfc3161ng
+    >> timestamper = rfc3161ng.RemoteTimestamper('https://interop.redwax.eu/test/timestamp', hashname='sha256')
+    >> tsr = timestamper(data=b'The RedWax Project', return_tsr=True)
+    >> print('{}'.format(tsr))
+
+Verifying timestamp using OpenSSL
+=================================
+
+One can verify the timestamp returned by the timeserver by using OpenSSL.
+For example with:
+
+  $ openssl ts -verify -data data_file.txt -in data_file.tsr -CAfile cacert.pem -untrusted tsa.crt
+
+To save the tsr you can use code similar to:
+
+    >>> from pyasn1.codec.der import encoder
+    >>> import rfc3161ng
+    >>> ...
+    >>> timestamper = rfc3161ng.RemoteTimestamper('http://freetsa.org/tsr', certificate=certificate_data)
+    >>> tsr = timestamper(data=data_file.read(), return_tsr=True)
+    >>> with open("data_file.tsr", "wb") as f:
+    >>>     f.write(encoder.encode(tsr))
+
+Alternatively you can just save the raw `response.content` returned from the certification server.
+
+There is a test which also covers this in `test_verify_timestamp_response_with_openssl`.
+
+
+Authors
+=======
+
+ * Benjamin Dauvergne <bdauvergne@entrouvert.com>
+ * Michael Gebetsroither <michael@mgeb.org>
+ * Bas van Oostveen <trbs@trbs.net>
diff --git a/creating_release.rst b/creating_release.rst
deleted file mode 100644
index 9cc1f4a..0000000
--- a/creating_release.rst
+++ /dev/null
@@ -1,46 +0,0 @@
-==================
-Creating a release
-==================
-
-:synopsis: Creating a rfc3161ng release
-
-
-How to make a new release
--------------------------
-
-Run tests::
-
-    $ tox -r
-
-Change version numbers in `setup.py` and `rfc3161ng/__init__.py`::
-
-    $ vi setup.py
-    $ vi rfc3161ng/__init__.py
-    $ git commit -m 'v2.0.0' setup.py rfc3161ng/__init__.py
-
-Tag it:
-
-    $ git tag 2.0.0
-
-Remove old build directory (if exists)::
-
-    $ rm -r build dist
-
-Prepare the release tarball::
-
-    $ python ./setup.py sdist bdist_wheel
-
-Upload release to pypi::
-
-    $ twine upload -s dist/*
-
-Bumb version number to new in-development pre version::
-
-    $ vi setup.py
-    $ vi rfc3161ng/__init__.py
-    $ git commit -m 'bumped version number' setup.py rfc3161ng/__init__.py
-
-Push changes back to github::
-
-    $ git push --tags
-    $ git push
diff --git a/data/freetsa_cacert.pem b/data/freetsa_cacert.pem
deleted file mode 100644
index c144895..0000000
--- a/data/freetsa_cacert.pem
+++ /dev/null
@@ -1,45 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIH/zCCBeegAwIBAgIJAMHphhYNqOmAMA0GCSqGSIb3DQEBDQUAMIGVMREwDwYD
-VQQKEwhGcmVlIFRTQTEQMA4GA1UECxMHUm9vdCBDQTEYMBYGA1UEAxMPd3d3LmZy
-ZWV0c2Eub3JnMSIwIAYJKoZIhvcNAQkBFhNidXNpbGV6YXNAZ21haWwuY29tMRIw
-EAYDVQQHEwlXdWVyemJ1cmcxDzANBgNVBAgTBkJheWVybjELMAkGA1UEBhMCREUw
-HhcNMTYwMzEzMDE1MjEzWhcNNDEwMzA3MDE1MjEzWjCBlTERMA8GA1UEChMIRnJl
-ZSBUU0ExEDAOBgNVBAsTB1Jvb3QgQ0ExGDAWBgNVBAMTD3d3dy5mcmVldHNhLm9y
-ZzEiMCAGCSqGSIb3DQEJARYTYnVzaWxlemFzQGdtYWlsLmNvbTESMBAGA1UEBxMJ
-V3VlcnpidXJnMQ8wDQYDVQQIEwZCYXllcm4xCzAJBgNVBAYTAkRFMIICIjANBgkq
-hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtgKODjAy8REQ2WTNqUudAnjhlCrpE6ql
-mQfNppeTmVvZrH4zutn+NwTaHAGpjSGv4/WRpZ1wZ3BRZ5mPUBZyLgq0YrIfQ5Fx
-0s/MRZPzc1r3lKWrMR9sAQx4mN4z11xFEO529L0dFJjPF9MD8Gpd2feWzGyptlel
-b+PqT+++fOa2oY0+NaMM7l/xcNHPOaMz0/2olk0i22hbKeVhvokPCqhFhzsuhKsm
-q4Of/o+t6dI7sx5h0nPMm4gGSRhfq+z6BTRgCrqQG2FOLoVFgt6iIm/BnNffUr7V
-DYd3zZmIwFOj/H3DKHoGik/xK3E82YA2ZulVOFRW/zj4ApjPa5OFbpIkd0pmzxzd
-EcL479hSA9dFiyVmSxPtY5ze1P+BE9bMU1PScpRzw8MHFXxyKqW13Qv7LWw4sbk3
-SciB7GACbQiVGzgkvXG6y85HOuvWNvC5GLSiyP9GlPB0V68tbxz4JVTRdw/Xn/XT
-FNzRBM3cq8lBOAVt/PAX5+uFcv1S9wFE8YjaBfWCP1jdBil+c4e+0tdywT2oJmYB
-BF/kEt1wmGwMmHunNEuQNzh1FtJY54hbUfiWi38mASE7xMtMhfj/C4SvapiDN837
-gYaPfs8x3KZxbX7C3YAsFnJinlwAUss1fdKar8Q/YVs7H/nU4c4Ixxxz4f67fcVq
-M2ITKentbCMCAwEAAaOCAk4wggJKMAwGA1UdEwQFMAMBAf8wDgYDVR0PAQH/BAQD
-AgHGMB0GA1UdDgQWBBT6VQ2MNGZRQ0z357OnbJWveuaklzCBygYDVR0jBIHCMIG/
-gBT6VQ2MNGZRQ0z357OnbJWveuakl6GBm6SBmDCBlTERMA8GA1UEChMIRnJlZSBU
-U0ExEDAOBgNVBAsTB1Jvb3QgQ0ExGDAWBgNVBAMTD3d3dy5mcmVldHNhLm9yZzEi
-MCAGCSqGSIb3DQEJARYTYnVzaWxlemFzQGdtYWlsLmNvbTESMBAGA1UEBxMJV3Vl
-cnpidXJnMQ8wDQYDVQQIEwZCYXllcm4xCzAJBgNVBAYTAkRFggkAwemGFg2o6YAw
-MwYDVR0fBCwwKjAooCagJIYiaHR0cDovL3d3dy5mcmVldHNhLm9yZy9yb290X2Nh
-LmNybDCBzwYDVR0gBIHHMIHEMIHBBgorBgEEAYHyJAEBMIGyMDMGCCsGAQUFBwIB
-FidodHRwOi8vd3d3LmZyZWV0c2Eub3JnL2ZyZWV0c2FfY3BzLmh0bWwwMgYIKwYB
-BQUHAgEWJmh0dHA6Ly93d3cuZnJlZXRzYS5vcmcvZnJlZXRzYV9jcHMucGRmMEcG
-CCsGAQUFBwICMDsaOUZyZWVUU0EgdHJ1c3RlZCB0aW1lc3RhbXBpbmcgU29mdHdh
-cmUgYXMgYSBTZXJ2aWNlIChTYWFTKTA3BggrBgEFBQcBAQQrMCkwJwYIKwYBBQUH
-MAGGG2h0dHA6Ly93d3cuZnJlZXRzYS5vcmc6MjU2MDANBgkqhkiG9w0BAQ0FAAOC
-AgEAaK9+v5OFYu9M6ztYC+L69sw1omdyli89lZAfpWMMh9CRmJhM6KBqM/ipwoLt
-nxyxGsbCPhcQjuTvzm+ylN6VwTMmIlVyVSLKYZcdSjt/eCUN+41K7sD7GVmxZBAF
-ILnBDmTGJmLkrU0KuuIpj8lI/E6Z6NnmuP2+RAQSHsfBQi6sssnXMo4HOW5gtPO7
-gDrUpVXID++1P4XndkoKn7Svw5n0zS9fv1hxBcYIHPPQUze2u30bAQt0n0iIyRLz
-aWuhtpAtd7ffwEbASgzB7E+NGF4tpV37e8KiA2xiGSRqT5ndu28fgpOY87gD3ArZ
-DctZvvTCfHdAS5kEO3gnGGeZEVLDmfEsv8TGJa3AljVa5E40IQDsUXpQLi8G+UC4
-1DWZu8EVT4rnYaCw1VX7ShOR1PNCCvjb8S8tfdudd9zhU3gEB0rxdeTy1tVbNLXW
-99y90xcwr1ZIDUwM/xQ/noO8FRhm0LoPC73Ef+J4ZBdrvWwauF3zJe33d4ibxEcb
-8/pz5WzFkeixYM2nsHhqHsBKw7JPouKNXRnl5IAE1eFmqDyC7G/VT7OF669xM6hb
-Ut5G21JE4cNK6NNucS+fzg1JPX0+3VhsYZjj7D5uljRvQXrJ8iHgr/M6j2oLHvTA
-I2MLdq2qjZFDOCXsxBxJpbmLGBx9ow6ZerlUxzws2AWv2pk=
------END CERTIFICATE-----
diff --git a/data/redwax-interop-ca.crt b/data/redwax-interop-ca.crt
new file mode 100644
index 0000000..a6f8a26
Binary files /dev/null and b/data/redwax-interop-ca.crt differ
diff --git a/debian/changelog b/debian/changelog
index 52d0510..8a54ae4 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+python-rfc3161ng (2.1.3+git20201030.1.edb6354-1) UNRELEASED; urgency=low
+
+  * New upstream snapshot.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Mon, 14 Nov 2022 16:39:05 -0000
+
 python-rfc3161ng (2.1.1-3) unstable; urgency=medium
 
   * Changed Standards-Version from 4.1.4 to 4.2.1.
diff --git a/README.rst b/rfc3161ng.egg-info/PKG-INFO
similarity index 65%
rename from README.rst
rename to rfc3161ng.egg-info/PKG-INFO
index 88c21a3..a3524bb 100644
--- a/README.rst
+++ b/rfc3161ng.egg-info/PKG-INFO
@@ -1,3 +1,27 @@
+Metadata-Version: 2.1
+Name: rfc3161ng
+Version: 2.1.4.dev0
+Summary: Python implementation of the RFC3161 specification, using pyasn1
+Home-page: https://dev.entrouvert.org/projects/python-rfc3161
+Author: Benjamin Dauvergne
+Author-email: bdauvergne@entrouvert.com
+Maintainer: trbs
+Maintainer-email: trbs@trbs.net
+License: MIT
+Platform: any
+Classifier: Environment :: Console
+Classifier: Intended Audience :: Developers
+Classifier: Intended Audience :: Information Technology
+Classifier: Intended Audience :: System Administrators
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Topic :: Communications
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Description-Content-Type: text/x-rst
+License-File: LICENSE
+
 =========
 rfc3161ng
 =========
@@ -5,9 +29,9 @@ rfc3161ng
 .. image:: https://img.shields.io/pypi/l/rfc3161ng.svg
    :target: https://raw.githubusercontent.com/trbs/rfc3161ng/master/LICENSE
 
-.. image:: https://travis-ci.org/trbs/rfc3161ng.svg?branch=master
-    :alt: Build Status
-    :target: https://travis-ci.org/trbs/rfc3161ng
+.. image:: https://github.com/trbs/rfc3161ng/workflows/CI/badge.svg?branch=master
+     :target: https://github.com/trbs/rfc3161ng/actions?workflow=CI
+     :alt: CI Status
 
 .. image:: https://img.shields.io/pypi/v/rfc3161ng.svg
     :target: https://pypi.python.org/pypi/rfc3161ng/
@@ -53,6 +77,12 @@ Example
     >>> rfc3161ng.get_timestamp(tst)
     datetime.datetime(2017, 8, 31, 15, 42, 58, tzinfo=tzutc())
 
+Example for a server that insist on SHA256:
+
+    >> import rfc3161ng
+    >> timestamper = rfc3161ng.RemoteTimestamper('https://interop.redwax.eu/test/timestamp', hashname='sha256')
+    >> tsr = timestamper(data=b'The RedWax Project', return_tsr=True)
+    >> print('{}'.format(tsr))
 
 Verifying timestamp using OpenSSL
 =================================
diff --git a/rfc3161ng.egg-info/SOURCES.txt b/rfc3161ng.egg-info/SOURCES.txt
new file mode 100644
index 0000000..6e200bf
--- /dev/null
+++ b/rfc3161ng.egg-info/SOURCES.txt
@@ -0,0 +1,23 @@
+LICENSE
+MANIFEST.in
+README.rst
+setup.cfg
+setup.py
+stdeb.cfg
+tox.ini
+data/certum_certificate.crt
+data/e_szigno_test_tsa2.crt
+data/fedict.crt
+data/freetsa.crt
+data/redwax-interop-ca.crt
+rfc3161ng/__init__.py
+rfc3161ng/api.py
+rfc3161ng/constants.py
+rfc3161ng/types.py
+rfc3161ng.egg-info/PKG-INFO
+rfc3161ng.egg-info/SOURCES.txt
+rfc3161ng.egg-info/dependency_links.txt
+rfc3161ng.egg-info/requires.txt
+rfc3161ng.egg-info/top_level.txt
+spec/schema.asn88
+tests/test_api.py
\ No newline at end of file
diff --git a/rfc3161ng.egg-info/dependency_links.txt b/rfc3161ng.egg-info/dependency_links.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/rfc3161ng.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
diff --git a/rfc3161ng.egg-info/requires.txt b/rfc3161ng.egg-info/requires.txt
new file mode 100644
index 0000000..13b9088
--- /dev/null
+++ b/rfc3161ng.egg-info/requires.txt
@@ -0,0 +1,5 @@
+cryptography
+pyasn1
+pyasn1_modules
+python-dateutil
+requests
diff --git a/rfc3161ng.egg-info/top_level.txt b/rfc3161ng.egg-info/top_level.txt
new file mode 100644
index 0000000..b42e7af
--- /dev/null
+++ b/rfc3161ng.egg-info/top_level.txt
@@ -0,0 +1 @@
+rfc3161ng
diff --git a/rfc3161ng/__init__.py b/rfc3161ng/__init__.py
index 4bdc5cb..6d90892 100644
--- a/rfc3161ng/__init__.py
+++ b/rfc3161ng/__init__.py
@@ -30,4 +30,4 @@ __all__ = (
     'decode_timestamp_request', 'decode_timestamp_response',
 )
 
-VERSION = '2.1.1'
+VERSION = '2.1.4-dev'
diff --git a/rfc3161ng/api.py b/rfc3161ng/api.py
index b85b639..9dec34a 100644
--- a/rfc3161ng/api.py
+++ b/rfc3161ng/api.py
@@ -48,44 +48,45 @@ class TimestampingError(RuntimeError):
 
 
 def generalizedtime_to_utc_datetime(gt, naive=True):
-    m = re.match('(?P<year>\d{4})(?P<month>\d{2})(?P<day>\d{2})(?P<hour>\d{2})(?:(?P<minutes>\d{2})(?:(?P<seconds>\d{2})(?:[.,](?P<fractions>\d*))?)?)?(?P<tz>Z|[+-]\d{2}(?:\d{2})?)?', gt)
-    if m:
-        d = m.groupdict()
-        dt = datetime.datetime(
-            int(d['year']),
-            int(d['month']),
-            int(d['day']),
-            int(d['hour']),
-            int(d['minutes'] or 0),
-            int(d['seconds'] or 0),
-            int(float('0.' + d['fractions']) * 1000000 if d['fractions'] else 0)
-        )
-        if naive:
-            if d['tz'] and d['tz'][0] in ('+', '-'):
-                diff = dateutil.relativedelta.relativedelta(
-                    hours=int(d['tz'][1:3]),
-                    minutes=int(d['tz'][3:5]) if len(d['tz']) > 3 else 0
-                )
-                if d['tz'][0] == '+':
-                    dt -= diff
-                else:
-                    dt += diff
-            return dt
-        else:
-            if d['tz'] and re.match('^[+\-]\d*[^0]\d*$', d['tz']):
-                diff = datetime.timedelta(
-                    hours=int(d['tz'][1:3]),
-                    minutes=int(d['tz'][3:5]) if len(d['tz']) > 3 else 0
-                ).total_seconds()
-                name = d['tz'][0:3]
-                if len(d['tz']) > 3:
-                    name += ':' + d['tz'][3:5]
-                dt = dt.replace(tzinfo=dateutil.tz.tzoffset(name, diff if d['tz'][0] == '+' else -diff))
+    m = re.match(r'(?P<year>\d{4})(?P<month>\d{2})(?P<day>\d{2})(?P<hour>\d{2})(?:(?P<minutes>\d{2})(?:(?P<seconds>\d{2})(?:[.,](?P<fractions>\d*))?)?)?(?P<tz>Z|[+-]\d{2}(?:\d{2})?)?', gt)
+    if not m:
+        raise ValueError("not an ASN.1 generalizedTime: '%s'" % (gt,))
+
+    d = m.groupdict()
+    dt = datetime.datetime(
+        int(d['year']),
+        int(d['month']),
+        int(d['day']),
+        int(d['hour']),
+        int(d['minutes'] or 0),
+        int(d['seconds'] or 0),
+        int(float('0.' + d['fractions']) * 1000000 if d['fractions'] else 0)
+    )
+    if naive:
+        if d['tz'] and d['tz'][0] in ('+', '-'):
+            diff = dateutil.relativedelta.relativedelta(
+                hours=int(d['tz'][1:3]),
+                minutes=int(d['tz'][3:5]) if len(d['tz']) > 3 else 0
+            )
+            if d['tz'][0] == '+':
+                dt -= diff
             else:
-                dt = dt.replace(tzinfo=dateutil.tz.tzutc())
-            return dt
+                dt += diff
+        return dt
+
+    if d['tz'] and re.match(r'^[+\-]\d*[^0]\d*$', d['tz']):
+        diff = datetime.timedelta(
+            hours=int(d['tz'][1:3]),
+            minutes=int(d['tz'][3:5]) if len(d['tz']) > 3 else 0
+        ).total_seconds()
+        name = d['tz'][0:3]
+        if len(d['tz']) > 3:
+            name += ':' + d['tz'][3:5]
+        dt = dt.replace(tzinfo=dateutil.tz.tzoffset(name, diff if d['tz'][0] == '+' else -diff))
     else:
-        raise ValueError("not an ASN.1 generalizedTime: '%s'" % (gt,))
+        dt = dt.replace(tzinfo=dateutil.tz.tzutc())
+
+    return dt
 
 
 def get_timestamp(tst, naive=True):
@@ -124,7 +125,7 @@ def load_certificate(signed_data, certificate=b""):
     return x509.load_der_x509_certificate(certificate, backend)
 
 
-def check_timestamp(tst, certificate, data=None, digest=None, hashname=None, nonce=None):
+def check_timestamp(tst, certificate=None, data=None, digest=None, hashname=None, nonce=None):
     hashname = hashname or 'sha1'
     hashobj = hashlib.new(hashname)
     if digest is None:
@@ -197,7 +198,7 @@ def check_timestamp(tst, certificate, data=None, digest=None, hashname=None, non
 
 
 class RemoteTimestamper(object):
-    def __init__(self, url, certificate=None, capath=None, cafile=None, username=None, password=None, hashname=None, include_tsa_certificate=False, timeout=10):
+    def __init__(self, url, certificate=None, capath=None, cafile=None, username=None, password=None, hashname=None, include_tsa_certificate=False, timeout=10, tsa_policy_id=None):
         self.url = url
         self.certificate = certificate
         self.capath = capath
@@ -207,13 +208,16 @@ class RemoteTimestamper(object):
         self.hashname = hashname or 'sha1'
         self.include_tsa_certificate = include_tsa_certificate
         self.timeout = timeout
+        self.tsa_policy_id = tsa_policy_id
 
     def check_response(self, response, digest, nonce=None):
         '''
            Check validity of a TimeStampResponse
         '''
         tst = response.time_stamp_token
-        return self.check(tst, digest=digest, nonce=nonce)
+        if self.certificate:
+            return self.check(tst, digest=digest, nonce=nonce)
+        return tst
 
     def check(self, tst, data=None, digest=None, nonce=None):
         return check_timestamp(
@@ -225,15 +229,16 @@ class RemoteTimestamper(object):
             hashname=self.hashname,
         )
 
-    def timestamp(self, data=None, digest=None, include_tsa_certificate=None, nonce=None):
+    def timestamp(self, data=None, digest=None, include_tsa_certificate=None, nonce=None, tsa_policy_id=None):
         return self(
             data=data,
             digest=digest,
             include_tsa_certificate=include_tsa_certificate,
             nonce=nonce,
+            tsa_policy_id=tsa_policy_id,
         )
 
-    def __call__(self, data=None, digest=None, include_tsa_certificate=None, nonce=None, return_tsr=False):
+    def __call__(self, data=None, digest=None, include_tsa_certificate=None, nonce=None, return_tsr=False, tsa_policy_id=None):
         if data:
             digest = data_to_digest(data, self.hashname)
 
@@ -243,6 +248,7 @@ class RemoteTimestamper(object):
             hashname=self.hashname,
             include_tsa_certificate=include_tsa_certificate if include_tsa_certificate is not None else self.include_tsa_certificate,
             nonce=nonce,
+            tsa_policy_id=tsa_policy_id if tsa_policy_id is not None else self.tsa_policy_id
         )
         binary_request = encode_timestamp_request(request)
 
@@ -279,7 +285,7 @@ def data_to_digest(data, hashname='sha1'):
     return hashobj.digest()
 
 
-def make_timestamp_request(data=None, digest=None, hashname='sha1', include_tsa_certificate=False, nonce=None):
+def make_timestamp_request(data=None, digest=None, hashname='sha1', include_tsa_certificate=False, nonce=None, tsa_policy_id=None):
     algorithm_identifier = rfc2459.AlgorithmIdentifier()
     algorithm_identifier.setComponentByPosition(0, get_hash_oid(hashname))
     message_imprint = rfc3161ng.MessageImprint()
@@ -295,6 +301,8 @@ def make_timestamp_request(data=None, digest=None, hashname='sha1', include_tsa_
     tsq = rfc3161ng.TimeStampReq()
     tsq.setComponentByPosition(0, 'v1')
     tsq.setComponentByPosition(1, message_imprint)
+    if tsa_policy_id:
+        tsq.setComponentByPosition(2, rfc3161ng.types.TSAPolicyId(tsa_policy_id))
     if nonce is not None:
         tsq.setComponentByPosition(3, int(nonce))
     tsq.setComponentByPosition(4, include_tsa_certificate)
diff --git a/rfc3161ng/types.py b/rfc3161ng/types.py
index b68ae76..8127919 100644
--- a/rfc3161ng/types.py
+++ b/rfc3161ng/types.py
@@ -1,5 +1,5 @@
 from pyasn1.type import univ, namedtype, tag, namedval, constraint, char, useful
-from pyasn1_modules.rfc2459 import AlgorithmIdentifier, Extensions, MAX
+from pyasn1_modules.rfc2459 import AlgorithmIdentifier, Extensions, MAX, Name
 from pyasn1_modules.rfc2315 import ContentInfo, signedData, SignedData
 from pyasn1.codec.ber import decoder
 
@@ -153,7 +153,7 @@ class GeneralName(univ.Choice):
         namedtype.NamedType('rfc822Name', char.IA5String().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))),
         # namedtype.NamedType('dNSName', univ.Any().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))),
         # namedtype.NamedType('x400Address', univ.Any().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))),
-        namedtype.NamedType('directoryName', univ.Any().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))),
+        namedtype.NamedType('directoryName', Name().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))),
         # namedtype.NamedType('ediPartyName', univ.Any().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 5))),
         # namedtype.NamedType('uniformResourceIdentifier', char.IA5String().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 6))),
         # namedtype.NamedType('iPAddress', univ.OctetString().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 7))),
diff --git a/setup.cfg b/setup.cfg
index 97bd017..cc77942 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -2,7 +2,7 @@
 universal = 1
 
 [egg_info]
-tag_build =
+tag_build = 
 tag_date = 0
 tag_svn_revision = 0
 
@@ -11,3 +11,7 @@ ignore = E265,W391
 max-line-length = 256
 exclude = .tox,.git,__pycache__,docs/source/conf.py,old,build,dist
 max-complexity = 20
+
+[pycodestyle]
+max-line-length = 256
+
diff --git a/setup.py b/setup.py
index 28b942e..ce8ec47 100755
--- a/setup.py
+++ b/setup.py
@@ -6,11 +6,12 @@ with open('README.rst', 'r') as f:
 
 setup(
     name='rfc3161ng',
-    version='2.1.1',
+    version='2.1.4-dev',
     license='MIT',
     url='https://dev.entrouvert.org/projects/python-rfc3161',
     description='Python implementation of the RFC3161 specification, using pyasn1',
     long_description=long_description,
+    long_description_content_type='text/x-rst',
     author='Benjamin Dauvergne',
     author_email='bdauvergne@entrouvert.com',
     maintainer='trbs',
diff --git a/tests/test_api.py b/tests/test_api.py
index 34806a2..c285f04 100755
--- a/tests/test_api.py
+++ b/tests/test_api.py
@@ -2,21 +2,23 @@ import os.path
 import datetime
 import dateutil.tz
 import subprocess
+import pytest
 
 from tempfile import NamedTemporaryFile
-# from pyasn1.type import univ
 from pyasn1.codec.der import encoder
 
 import rfc3161ng
 
 
-def _default_test(tsa_server, certificate, username=None, password=None, data='xx', nonce=None, **kwargs):
-    with open(certificate, 'rb') as f:
-        certificate_data = f.read()
+def _default_test(tsa_server, certificate=None, username=None, password=None, data='xx', nonce=None, **kwargs):
+    if certificate:
+        with open(certificate, 'rb') as f:
+            certificate_data = f.read()
+
+        kwargs.update({
+            'certificate': certificate_data,
+        })
 
-    kwargs.update({
-        'certificate': certificate_data,
-    })
     if username and password:
         kwargs.update({
             'username': username,
@@ -59,6 +61,31 @@ def test_time_certum_pl():
     )
 
 
+@pytest.mark.xfail
+def test_redwax_eu():
+    # https://interop.redwax.eu/rs/timestamp/
+    # CA:  https://interop.redwax.eu/test/simple/ca.der
+    # Server: 'https://interop.redwax.eu/test/timestamp
+    _default_test(
+        'https://interop.redwax.eu/test/timestamp',
+        certificate=os.path.join('data/redwax-interop-ca.crt'),
+        data=b'The RedWax Project',
+        hashname='sha256',
+    )
+
+
+@pytest.mark.xfail
+def test_redwax_eu_no_certificate():
+    # https://interop.redwax.eu/rs/timestamp/
+    # CA:  https://interop.redwax.eu/test/simple/ca.der
+    # Server: 'https://interop.redwax.eu/test/timestamp
+    _default_test(
+        'https://interop.redwax.eu/test/timestamp',
+        data=b'The RedWax Project',
+        hashname='sha256',
+    )
+
+
 def test_freetsa_org():
     _default_test(
         'http://freetsa.org/tsr',
@@ -119,4 +146,3 @@ def test_generalized_time_decoding():
     assert generalizedtime_to_utc_datetime('20180208181004.948468Z', False) == datetime.datetime(2018, 2, 8, 18, 10, 4, 948468, tzinfo=dateutil.tz.tzutc())
     assert generalizedtime_to_utc_datetime('20180208181004.948468-01', False) == datetime.datetime(2018, 2, 8, 19, 10, 4, 948468, tzinfo=dateutil.tz.tzutc())
     assert generalizedtime_to_utc_datetime('20180208181004.948468+0130', False) == datetime.datetime(2018, 2, 8, 16, 40, 4, 948468, tzinfo=dateutil.tz.tzutc())
-
diff --git a/tox.ini b/tox.ini
index 5483434..7f6bdd3 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,9 @@
 [tox]
-envlist = py27, py36, py37
+envlist = py38
+
+[gh-actions]
+python =
+    3.8: py38
 
 [testenv]
 setenv =
@@ -9,4 +13,5 @@ deps =
     pytest
 commands =
     flake8 rfc3161ng tests
-    py.test {posargs:tests/}
+    pip install -e .
+    py.test -ra -v {posargs:tests/}

More details

Full run details