aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/hazmat/primitives/twofactor.rst24
-rw-r--r--docs/spelling_wordlist.txt2
-rw-r--r--src/cryptography/hazmat/primitives/twofactor/hotp.py5
-rw-r--r--src/cryptography/hazmat/primitives/twofactor/totp.py5
-rw-r--r--tests/hazmat/primitives/twofactor/test_hotp.py4
5 files changed, 34 insertions, 6 deletions
diff --git a/docs/hazmat/primitives/twofactor.rst b/docs/hazmat/primitives/twofactor.rst
index 9268f2fa..a1391fae 100644
--- a/docs/hazmat/primitives/twofactor.rst
+++ b/docs/hazmat/primitives/twofactor.rst
@@ -18,7 +18,7 @@ codes (HMAC).
.. currentmodule:: cryptography.hazmat.primitives.twofactor.hotp
-.. class:: HOTP(key, length, algorithm, backend)
+.. class:: HOTP(key, length, algorithm, backend, enforce_key_length=True)
.. versionadded:: 0.3
@@ -50,6 +50,16 @@ codes (HMAC).
:param backend: A
:class:`~cryptography.hazmat.backends.interfaces.HMACBackend`
provider.
+ :param enforce_key_length: A boolean flag defaulting to True that toggles
+ whether a minimum key length of 128 bits is enforced. This exists to
+ work around the fact that as documented in `Issue #2915`, the
+ Google Authenticator PAM module by default generates 80 bit keys. If
+ this flag is set to False, the application develop should implement
+ additional checks of the key length before passing it into
+ :class:`~cryptography.hazmat.primitives.twofactor.hotp.HOTP`.
+
+ .. versionadded:: 1.5
+
:raises ValueError: This is raised if the provided ``key`` is shorter than
128 bits or if the ``length`` parameter is not 6, 7 or 8.
:raises TypeError: This is raised if the provided ``algorithm`` is not
@@ -129,7 +139,7 @@ similar to the following code.
.. currentmodule:: cryptography.hazmat.primitives.twofactor.totp
-.. class:: TOTP(key, length, algorithm, time_step, backend)
+.. class:: TOTP(key, length, algorithm, time_step, backend, enforce_key_length=True)
TOTP objects take a ``key``, ``length``, ``algorithm`` and ``time_step``
parameter. The ``key`` should be :doc:`randomly generated bytes
@@ -163,6 +173,15 @@ similar to the following code.
:param backend: A
:class:`~cryptography.hazmat.backends.interfaces.HMACBackend`
provider.
+ :param enforce_key_length: A boolean flag defaulting to True that toggles
+ whether a minimum key length of 128 bits is enforced. This exists to
+ work around the fact that as documented in `Issue #2915`, the
+ Google Authenticator PAM module by default generates 80 bit keys. If
+ this flag is set to False, the application develop should implement
+ additional checks of the key length before passing it into
+ :class:`~cryptography.hazmat.primitives.twofactor.totp.TOTP`.
+
+ .. versionadded:: 1.5
:raises ValueError: This is raised if the provided ``key`` is shorter than
128 bits or if the ``length`` parameter is not 6, 7 or 8.
:raises TypeError: This is raised if the provided ``algorithm`` is not
@@ -222,3 +241,4 @@ A common usage is encoding the provisioning URI into QR code and guiding users
to scan it with Two-Factor authentication applications in their mobile devices.
.. _`spec of Google Authenticator`: https://github.com/google/google-authenticator/wiki/Key-Uri-Format
+.. _`Issue #2915`: https://github.com/pyca/cryptography/issues/2915
diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt
index 47415a7e..064c7388 100644
--- a/docs/spelling_wordlist.txt
+++ b/docs/spelling_wordlist.txt
@@ -72,3 +72,5 @@ unpadding
Verisign
wildcard
Xcode
+Google
+Authenticator
diff --git a/src/cryptography/hazmat/primitives/twofactor/hotp.py b/src/cryptography/hazmat/primitives/twofactor/hotp.py
index 12bc7661..4ad1bdc2 100644
--- a/src/cryptography/hazmat/primitives/twofactor/hotp.py
+++ b/src/cryptography/hazmat/primitives/twofactor/hotp.py
@@ -19,14 +19,15 @@ from cryptography.hazmat.primitives.twofactor.utils import _generate_uri
class HOTP(object):
- def __init__(self, key, length, algorithm, backend):
+ def __init__(self, key, length, algorithm, backend,
+ enforce_key_length=True):
if not isinstance(backend, HMACBackend):
raise UnsupportedAlgorithm(
"Backend object does not implement HMACBackend.",
_Reasons.BACKEND_MISSING_INTERFACE
)
- if len(key) < 16:
+ if len(key) < 16 and enforce_key_length is True:
raise ValueError("Key length has to be at least 128 bits.")
if not isinstance(length, six.integer_types):
diff --git a/src/cryptography/hazmat/primitives/twofactor/totp.py b/src/cryptography/hazmat/primitives/twofactor/totp.py
index 60705901..499f2824 100644
--- a/src/cryptography/hazmat/primitives/twofactor/totp.py
+++ b/src/cryptography/hazmat/primitives/twofactor/totp.py
@@ -15,7 +15,8 @@ from cryptography.hazmat.primitives.twofactor.utils import _generate_uri
class TOTP(object):
- def __init__(self, key, length, algorithm, time_step, backend):
+ def __init__(self, key, length, algorithm, time_step, backend,
+ enforce_key_length=True):
if not isinstance(backend, HMACBackend):
raise UnsupportedAlgorithm(
"Backend object does not implement HMACBackend.",
@@ -23,7 +24,7 @@ class TOTP(object):
)
self._time_step = time_step
- self._hotp = HOTP(key, length, algorithm, backend)
+ self._hotp = HOTP(key, length, algorithm, backend, enforce_key_length)
def generate(self, time):
counter = int(time / self._time_step)
diff --git a/tests/hazmat/primitives/twofactor/test_hotp.py b/tests/hazmat/primitives/twofactor/test_hotp.py
index ab5f93c5..4c561f70 100644
--- a/tests/hazmat/primitives/twofactor/test_hotp.py
+++ b/tests/hazmat/primitives/twofactor/test_hotp.py
@@ -35,6 +35,10 @@ class TestHOTP(object):
with pytest.raises(ValueError):
HOTP(secret, 6, SHA1(), backend)
+ def test_unenforced_invalid_kwy_length(self, backend):
+ secret = os.urandom(10)
+ HOTP(secret, 6, SHA1(), backend, enforce_key_length=False)
+
def test_invalid_hotp_length(self, backend):
secret = os.urandom(16)