PyOTP 2.2.6__tar.gz → 2.2.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,6 @@
1
- Copyright (C) 2011-2016 Mark Percival <m@mdp.im>,
2
- Nathan Reynolds <email@nreynolds.co.uk>, and PyOTP contributors
1
+ Copyright (C) 2011-2017 Mark Percival <m@mdp.im>,
2
+ Nathan Reynolds <email@nreynolds.co.uk>, Andrey Kislyuk <kislyuk@gmail.com>,
3
+ and PyOTP contributors
3
4
 
4
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
5
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 1.1
2
2
  Name: pyotp
3
- Version: 2.2.6
3
+ Version: 2.2.8
4
4
  Summary: Python One Time Password Library
5
5
  Home-page: https://github.com/pyotp/pyotp
6
6
  Author: PyOTP contributors
7
7
  Author-email: kislyuk@gmail.com
8
- License: BSD License
8
+ License: MIT License
9
9
  Description: PyOTP - The Python One-Time Password Library
10
10
  ============================================
11
11
 
@@ -20,7 +20,27 @@ Description: PyOTP - The Python One-Time Password Library
20
20
  compatible app. Users can set up auth tokens in their apps easily by using their phone camera to scan `otpauth://
21
21
  <https://github.com/google/google-authenticator/wiki/Key-Uri-Format>`_ QR codes provided by PyOTP.
22
22
 
23
- We recommend that implementers read the `OWASP Authentication Cheat Sheet <https://www.owasp.org/index.php/Authentication_Cheat_Sheet>`_ and `NIST SP 800-63-3: Digital Authentication Guideline <https://pages.nist.gov/800-63-3/>`_ for a high level overview of authentication best practices.
23
+ Implementers should read and follow the `HOTP security requirements <https://tools.ietf.org/html/rfc4226#section-7>`_
24
+ and `TOTP security considerations <https://tools.ietf.org/html/rfc6238#section-5>`_ sections of the relevant RFCs. At
25
+ minimum, application implementers should follow this checklist:
26
+
27
+ - Ensure transport confidentiality by using HTTPS
28
+ - Ensure HOTP/TOTP secret confidentiality by storing secrets in a controlled access database
29
+ - Deny replay attacks by rejecting one-time passwords that have been used by the client (this requires storing the most
30
+ recently authenticated timestamp, OTP, or hash of the OTP in your database, and rejecting the OTP when a match is seen)
31
+ - Throttle brute-force attacks against your application's login functionality
32
+ - When implementing a "greenfield" application, consider supporting
33
+ `FIDO U2F <https://en.wikipedia.org/wiki/Universal_2nd_Factor>`_/`WebAuthn <https://www.w3.org/TR/webauthn/>`_ in
34
+ addition to HOTP/TOTP. U2F uses asymmetric cryptography to avoid using a shared secret design, which strengthens your
35
+ MFA solution against server-side attacks. Hardware U2F also sequesters the client secret in a dedicated single-purpose
36
+ device, which strengthens your clients against client-side attacks. And by automating scoping of credentials to
37
+ relying party IDs (application origin/domain names), U2F adds protection against phishing attacks. One implementation of
38
+ FIDO U2F/WebAuthn is PyOTP's sister project, `PyWARP <https://github.com/pyauth/pywarp>`_.
39
+
40
+ We also recommend that implementers read the
41
+ `OWASP Authentication Cheat Sheet <https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Authentication_Cheat_Sheet.md>`_ and
42
+ `NIST SP 800-63-3: Digital Authentication Guideline <https://pages.nist.gov/800-63-3/>`_ for a high level overview of
43
+ authentication best practices.
24
44
 
25
45
  Quick overview of using One Time Passwords on your phone
26
46
  --------------------------------------------------------
@@ -44,25 +64,25 @@ Description: PyOTP - The Python One-Time Password Library
44
64
  ::
45
65
 
46
66
  totp = pyotp.TOTP('base32secret3232')
47
- totp.now() # => 492039
67
+ totp.now() # => '492039'
48
68
 
49
69
  # OTP verified for current time
50
- totp.verify(492039) # => True
70
+ totp.verify('492039') # => True
51
71
  time.sleep(30)
52
- totp.verify(492039) # => False
72
+ totp.verify('492039') # => False
53
73
 
54
74
  Counter-based OTPs
55
75
  ~~~~~~~~~~~~~~~~~~
56
76
  ::
57
77
 
58
78
  hotp = pyotp.HOTP('base32secret3232')
59
- hotp.at(0) # => 260182
60
- hotp.at(1) # => 55283
61
- hotp.at(1401) # => 316439
79
+ hotp.at(0) # => '260182'
80
+ hotp.at(1) # => '055283'
81
+ hotp.at(1401) # => '316439'
62
82
 
63
83
  # OTP verified with a counter
64
- hotp.verify(316439, 1401) # => True
65
- hotp.verify(316439, 1402) # => False
84
+ hotp.verify('316439', 1401) # => True
85
+ hotp.verify('316439', 1402) # => False
66
86
 
67
87
  Generating a base32 Secret Key
68
88
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -92,7 +112,7 @@ Description: PyOTP - The Python One-Time Password Library
92
112
 
93
113
  Scan the following barcode with your phone's OTP app (e.g. Google Authenticator):
94
114
 
95
- .. image:: http://chart.apis.google.com/chart?cht=qr&chs=250x250&chl=otpauth%3A%2F%2Ftotp%2Falice%40google.com%3Fsecret%3DJBSWY3DPEHPK3PXP
115
+ .. image:: https://chart.apis.google.com/chart?cht=qr&chs=250x250&chl=otpauth%3A%2F%2Ftotp%2Falice%40google.com%3Fsecret%3DJBSWY3DPEHPK3PXP
96
116
 
97
117
  Now run the following and compare the output::
98
118
 
@@ -111,9 +131,14 @@ Description: PyOTP - The Python One-Time Password Library
111
131
  * `RFC 6238: TOTP: Time-Based One-Time Password Algorithm <https://tools.ietf.org/html/rfc6238>`_
112
132
  * `ROTP <https://github.com/mdp/rotp>`_ - Original Ruby OTP library by `Mark Percival <https://github.com/mdp>`_
113
133
  * `OTPHP <https://github.com/lelag/otphp>`_ - PHP port of ROTP by `Le Lag <https://github.com/lelag>`_
114
- * `OWASP Authentication Cheat Sheet <https://www.owasp.org/index.php/Authentication_Cheat_Sheet>`_
134
+ * `OWASP Authentication Cheat Sheet <https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Authentication_Cheat_Sheet.md>`_
115
135
  * `NIST SP 800-63-3: Digital Authentication Guideline <https://pages.nist.gov/800-63-3/>`_
116
136
 
137
+ For new applications:
138
+
139
+ * `WebAuthn <https://www.w3.org/TR/webauthn/>`_
140
+ * `PyWARP <https://github.com/pyauth/pywarp>`_
141
+
117
142
  .. image:: https://img.shields.io/travis/pyotp/pyotp.svg
118
143
  :target: https://travis-ci.org/pyotp/pyotp
119
144
  .. image:: https://img.shields.io/codecov/c/github/pyotp/pyotp/master.svg
@@ -128,11 +153,13 @@ Description: PyOTP - The Python One-Time Password Library
128
153
  Platform: MacOS X
129
154
  Platform: Posix
130
155
  Classifier: Intended Audience :: Developers
131
- Classifier: License :: OSI Approved :: BSD License
156
+ Classifier: License :: OSI Approved :: MIT License
132
157
  Classifier: Operating System :: MacOS :: MacOS X
133
158
  Classifier: Operating System :: POSIX
134
159
  Classifier: Programming Language :: Python
135
160
  Classifier: Programming Language :: Python :: 2.7
136
- Classifier: Programming Language :: Python :: 3.3
137
161
  Classifier: Programming Language :: Python :: 3.4
162
+ Classifier: Programming Language :: Python :: 3.5
163
+ Classifier: Programming Language :: Python :: 3.6
164
+ Classifier: Programming Language :: Python :: 3.7
138
165
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
@@ -12,7 +12,27 @@ Authenticator <https://en.wikipedia.org/wiki/Google_Authenticator>`_, `Authy <ht
12
12
  compatible app. Users can set up auth tokens in their apps easily by using their phone camera to scan `otpauth://
13
13
  <https://github.com/google/google-authenticator/wiki/Key-Uri-Format>`_ QR codes provided by PyOTP.
14
14
 
15
- We recommend that implementers read the `OWASP Authentication Cheat Sheet <https://www.owasp.org/index.php/Authentication_Cheat_Sheet>`_ and `NIST SP 800-63-3: Digital Authentication Guideline <https://pages.nist.gov/800-63-3/>`_ for a high level overview of authentication best practices.
15
+ Implementers should read and follow the `HOTP security requirements <https://tools.ietf.org/html/rfc4226#section-7>`_
16
+ and `TOTP security considerations <https://tools.ietf.org/html/rfc6238#section-5>`_ sections of the relevant RFCs. At
17
+ minimum, application implementers should follow this checklist:
18
+
19
+ - Ensure transport confidentiality by using HTTPS
20
+ - Ensure HOTP/TOTP secret confidentiality by storing secrets in a controlled access database
21
+ - Deny replay attacks by rejecting one-time passwords that have been used by the client (this requires storing the most
22
+ recently authenticated timestamp, OTP, or hash of the OTP in your database, and rejecting the OTP when a match is seen)
23
+ - Throttle brute-force attacks against your application's login functionality
24
+ - When implementing a "greenfield" application, consider supporting
25
+ `FIDO U2F <https://en.wikipedia.org/wiki/Universal_2nd_Factor>`_/`WebAuthn <https://www.w3.org/TR/webauthn/>`_ in
26
+ addition to HOTP/TOTP. U2F uses asymmetric cryptography to avoid using a shared secret design, which strengthens your
27
+ MFA solution against server-side attacks. Hardware U2F also sequesters the client secret in a dedicated single-purpose
28
+ device, which strengthens your clients against client-side attacks. And by automating scoping of credentials to
29
+ relying party IDs (application origin/domain names), U2F adds protection against phishing attacks. One implementation of
30
+ FIDO U2F/WebAuthn is PyOTP's sister project, `PyWARP <https://github.com/pyauth/pywarp>`_.
31
+
32
+ We also recommend that implementers read the
33
+ `OWASP Authentication Cheat Sheet <https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Authentication_Cheat_Sheet.md>`_ and
34
+ `NIST SP 800-63-3: Digital Authentication Guideline <https://pages.nist.gov/800-63-3/>`_ for a high level overview of
35
+ authentication best practices.
16
36
 
17
37
  Quick overview of using One Time Passwords on your phone
18
38
  --------------------------------------------------------
@@ -36,25 +56,25 @@ Time-based OTPs
36
56
  ::
37
57
 
38
58
  totp = pyotp.TOTP('base32secret3232')
39
- totp.now() # => 492039
59
+ totp.now() # => '492039'
40
60
 
41
61
  # OTP verified for current time
42
- totp.verify(492039) # => True
62
+ totp.verify('492039') # => True
43
63
  time.sleep(30)
44
- totp.verify(492039) # => False
64
+ totp.verify('492039') # => False
45
65
 
46
66
  Counter-based OTPs
47
67
  ~~~~~~~~~~~~~~~~~~
48
68
  ::
49
69
 
50
70
  hotp = pyotp.HOTP('base32secret3232')
51
- hotp.at(0) # => 260182
52
- hotp.at(1) # => 55283
53
- hotp.at(1401) # => 316439
71
+ hotp.at(0) # => '260182'
72
+ hotp.at(1) # => '055283'
73
+ hotp.at(1401) # => '316439'
54
74
 
55
75
  # OTP verified with a counter
56
- hotp.verify(316439, 1401) # => True
57
- hotp.verify(316439, 1402) # => False
76
+ hotp.verify('316439', 1401) # => True
77
+ hotp.verify('316439', 1402) # => False
58
78
 
59
79
  Generating a base32 Secret Key
60
80
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -84,7 +104,7 @@ Working example
84
104
 
85
105
  Scan the following barcode with your phone's OTP app (e.g. Google Authenticator):
86
106
 
87
- .. image:: http://chart.apis.google.com/chart?cht=qr&chs=250x250&chl=otpauth%3A%2F%2Ftotp%2Falice%40google.com%3Fsecret%3DJBSWY3DPEHPK3PXP
107
+ .. image:: https://chart.apis.google.com/chart?cht=qr&chs=250x250&chl=otpauth%3A%2F%2Ftotp%2Falice%40google.com%3Fsecret%3DJBSWY3DPEHPK3PXP
88
108
 
89
109
  Now run the following and compare the output::
90
110
 
@@ -103,9 +123,14 @@ Links
103
123
  * `RFC 6238: TOTP: Time-Based One-Time Password Algorithm <https://tools.ietf.org/html/rfc6238>`_
104
124
  * `ROTP <https://github.com/mdp/rotp>`_ - Original Ruby OTP library by `Mark Percival <https://github.com/mdp>`_
105
125
  * `OTPHP <https://github.com/lelag/otphp>`_ - PHP port of ROTP by `Le Lag <https://github.com/lelag>`_
106
- * `OWASP Authentication Cheat Sheet <https://www.owasp.org/index.php/Authentication_Cheat_Sheet>`_
126
+ * `OWASP Authentication Cheat Sheet <https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Authentication_Cheat_Sheet.md>`_
107
127
  * `NIST SP 800-63-3: Digital Authentication Guideline <https://pages.nist.gov/800-63-3/>`_
108
128
 
129
+ For new applications:
130
+
131
+ * `WebAuthn <https://www.w3.org/TR/webauthn/>`_
132
+ * `PyWARP <https://github.com/pyauth/pywarp>`_
133
+
109
134
  .. image:: https://img.shields.io/travis/pyotp/pyotp.svg
110
135
  :target: https://travis-ci.org/pyotp/pyotp
111
136
  .. image:: https://img.shields.io/codecov/c/github/pyotp/pyotp/master.svg
@@ -3,7 +3,7 @@ universal = 1
3
3
 
4
4
  [flake8]
5
5
  max-line-length = 120
6
- ignore = E301, E302, E305, E401, E226, F841
6
+ ignore = E301, E302, W504
7
7
 
8
8
  [egg_info]
9
9
  tag_build =
@@ -7,9 +7,9 @@ install_requires = [line.rstrip() for line in open(os.path.join(os.path.dirname(
7
7
 
8
8
  setup(
9
9
  name="pyotp",
10
- version="2.2.6",
10
+ version="2.2.8",
11
11
  url="https://github.com/pyotp/pyotp",
12
- license="BSD License",
12
+ license="MIT License",
13
13
  author="PyOTP contributors",
14
14
  author_email="kislyuk@gmail.com",
15
15
  description="Python One Time Password Library",
@@ -22,13 +22,15 @@ setup(
22
22
  test_suite="test",
23
23
  classifiers=[
24
24
  "Intended Audience :: Developers",
25
- "License :: OSI Approved :: BSD License",
25
+ "License :: OSI Approved :: MIT License",
26
26
  "Operating System :: MacOS :: MacOS X",
27
27
  "Operating System :: POSIX",
28
28
  "Programming Language :: Python",
29
29
  "Programming Language :: Python :: 2.7",
30
- "Programming Language :: Python :: 3.3",
31
30
  "Programming Language :: Python :: 3.4",
31
+ "Programming Language :: Python :: 3.5",
32
+ "Programming Language :: Python :: 3.6",
33
+ "Programming Language :: Python :: 3.7",
32
34
  "Topic :: Software Development :: Libraries :: Python Modules"
33
35
  ]
34
36
  )
@@ -1,16 +1,22 @@
1
1
  from __future__ import (absolute_import, division,
2
2
  print_function, unicode_literals)
3
3
 
4
- import random as _random
5
-
6
4
  from pyotp.hotp import HOTP # noqa
7
5
  from pyotp.otp import OTP # noqa
8
6
  from pyotp.totp import TOTP # noqa
9
7
  from . import utils # noqa
10
8
 
11
-
12
- def random_base32(length=16, random=_random.SystemRandom(),
9
+ def random_base32(length=16, random=None,
13
10
  chars=list('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567')):
11
+
12
+ # Use secrets module if available (Python version >= 3.6) per PEP 506
13
+ try:
14
+ import secrets
15
+ random = secrets.SystemRandom()
16
+ except ImportError:
17
+ import random as _random
18
+ random = _random.SystemRandom()
19
+
14
20
  return ''.join(
15
21
  random.choice(chars)
16
22
  for _ in range(length)
@@ -21,7 +21,7 @@ class HOTP(OTP):
21
21
 
22
22
  def verify(self, otp, counter):
23
23
  """
24
- Verifies the OTP passed in against the current time OTP.
24
+ Verifies the OTP passed in against the current counter OTP.
25
25
 
26
26
  :param otp: the OTP to check against
27
27
  :type otp: str
@@ -85,12 +85,12 @@ def _compare_digest(s1, s2):
85
85
  differences |= ord(c1) ^ ord(c2)
86
86
  return differences == 0
87
87
 
88
+
88
89
  try:
89
90
  # Python 3.3+ and 2.7.7+ include a timing-attack-resistant
90
91
  # comparison function, which is probably more reliable than ours.
91
92
  # Use it if available.
92
93
  from hmac import compare_digest
93
-
94
94
  except ImportError:
95
95
  compare_digest = _compare_digest
96
96
 
@@ -106,4 +106,4 @@ def strings_equal(s1, s2):
106
106
  """
107
107
  s1 = unicodedata.normalize('NFKC', s1)
108
108
  s2 = unicodedata.normalize('NFKC', s2)
109
- return compare_digest(s1, s2)
109
+ return compare_digest(s1.encode(), s2.encode())
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 1.1
2
2
  Name: pyotp
3
- Version: 2.2.6
3
+ Version: 2.2.8
4
4
  Summary: Python One Time Password Library
5
5
  Home-page: https://github.com/pyotp/pyotp
6
6
  Author: PyOTP contributors
7
7
  Author-email: kislyuk@gmail.com
8
- License: BSD License
8
+ License: MIT License
9
9
  Description: PyOTP - The Python One-Time Password Library
10
10
  ============================================
11
11
 
@@ -20,7 +20,27 @@ Description: PyOTP - The Python One-Time Password Library
20
20
  compatible app. Users can set up auth tokens in their apps easily by using their phone camera to scan `otpauth://
21
21
  <https://github.com/google/google-authenticator/wiki/Key-Uri-Format>`_ QR codes provided by PyOTP.
22
22
 
23
- We recommend that implementers read the `OWASP Authentication Cheat Sheet <https://www.owasp.org/index.php/Authentication_Cheat_Sheet>`_ and `NIST SP 800-63-3: Digital Authentication Guideline <https://pages.nist.gov/800-63-3/>`_ for a high level overview of authentication best practices.
23
+ Implementers should read and follow the `HOTP security requirements <https://tools.ietf.org/html/rfc4226#section-7>`_
24
+ and `TOTP security considerations <https://tools.ietf.org/html/rfc6238#section-5>`_ sections of the relevant RFCs. At
25
+ minimum, application implementers should follow this checklist:
26
+
27
+ - Ensure transport confidentiality by using HTTPS
28
+ - Ensure HOTP/TOTP secret confidentiality by storing secrets in a controlled access database
29
+ - Deny replay attacks by rejecting one-time passwords that have been used by the client (this requires storing the most
30
+ recently authenticated timestamp, OTP, or hash of the OTP in your database, and rejecting the OTP when a match is seen)
31
+ - Throttle brute-force attacks against your application's login functionality
32
+ - When implementing a "greenfield" application, consider supporting
33
+ `FIDO U2F <https://en.wikipedia.org/wiki/Universal_2nd_Factor>`_/`WebAuthn <https://www.w3.org/TR/webauthn/>`_ in
34
+ addition to HOTP/TOTP. U2F uses asymmetric cryptography to avoid using a shared secret design, which strengthens your
35
+ MFA solution against server-side attacks. Hardware U2F also sequesters the client secret in a dedicated single-purpose
36
+ device, which strengthens your clients against client-side attacks. And by automating scoping of credentials to
37
+ relying party IDs (application origin/domain names), U2F adds protection against phishing attacks. One implementation of
38
+ FIDO U2F/WebAuthn is PyOTP's sister project, `PyWARP <https://github.com/pyauth/pywarp>`_.
39
+
40
+ We also recommend that implementers read the
41
+ `OWASP Authentication Cheat Sheet <https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Authentication_Cheat_Sheet.md>`_ and
42
+ `NIST SP 800-63-3: Digital Authentication Guideline <https://pages.nist.gov/800-63-3/>`_ for a high level overview of
43
+ authentication best practices.
24
44
 
25
45
  Quick overview of using One Time Passwords on your phone
26
46
  --------------------------------------------------------
@@ -44,25 +64,25 @@ Description: PyOTP - The Python One-Time Password Library
44
64
  ::
45
65
 
46
66
  totp = pyotp.TOTP('base32secret3232')
47
- totp.now() # => 492039
67
+ totp.now() # => '492039'
48
68
 
49
69
  # OTP verified for current time
50
- totp.verify(492039) # => True
70
+ totp.verify('492039') # => True
51
71
  time.sleep(30)
52
- totp.verify(492039) # => False
72
+ totp.verify('492039') # => False
53
73
 
54
74
  Counter-based OTPs
55
75
  ~~~~~~~~~~~~~~~~~~
56
76
  ::
57
77
 
58
78
  hotp = pyotp.HOTP('base32secret3232')
59
- hotp.at(0) # => 260182
60
- hotp.at(1) # => 55283
61
- hotp.at(1401) # => 316439
79
+ hotp.at(0) # => '260182'
80
+ hotp.at(1) # => '055283'
81
+ hotp.at(1401) # => '316439'
62
82
 
63
83
  # OTP verified with a counter
64
- hotp.verify(316439, 1401) # => True
65
- hotp.verify(316439, 1402) # => False
84
+ hotp.verify('316439', 1401) # => True
85
+ hotp.verify('316439', 1402) # => False
66
86
 
67
87
  Generating a base32 Secret Key
68
88
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -92,7 +112,7 @@ Description: PyOTP - The Python One-Time Password Library
92
112
 
93
113
  Scan the following barcode with your phone's OTP app (e.g. Google Authenticator):
94
114
 
95
- .. image:: http://chart.apis.google.com/chart?cht=qr&chs=250x250&chl=otpauth%3A%2F%2Ftotp%2Falice%40google.com%3Fsecret%3DJBSWY3DPEHPK3PXP
115
+ .. image:: https://chart.apis.google.com/chart?cht=qr&chs=250x250&chl=otpauth%3A%2F%2Ftotp%2Falice%40google.com%3Fsecret%3DJBSWY3DPEHPK3PXP
96
116
 
97
117
  Now run the following and compare the output::
98
118
 
@@ -111,9 +131,14 @@ Description: PyOTP - The Python One-Time Password Library
111
131
  * `RFC 6238: TOTP: Time-Based One-Time Password Algorithm <https://tools.ietf.org/html/rfc6238>`_
112
132
  * `ROTP <https://github.com/mdp/rotp>`_ - Original Ruby OTP library by `Mark Percival <https://github.com/mdp>`_
113
133
  * `OTPHP <https://github.com/lelag/otphp>`_ - PHP port of ROTP by `Le Lag <https://github.com/lelag>`_
114
- * `OWASP Authentication Cheat Sheet <https://www.owasp.org/index.php/Authentication_Cheat_Sheet>`_
134
+ * `OWASP Authentication Cheat Sheet <https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Authentication_Cheat_Sheet.md>`_
115
135
  * `NIST SP 800-63-3: Digital Authentication Guideline <https://pages.nist.gov/800-63-3/>`_
116
136
 
137
+ For new applications:
138
+
139
+ * `WebAuthn <https://www.w3.org/TR/webauthn/>`_
140
+ * `PyWARP <https://github.com/pyauth/pywarp>`_
141
+
117
142
  .. image:: https://img.shields.io/travis/pyotp/pyotp.svg
118
143
  :target: https://travis-ci.org/pyotp/pyotp
119
144
  .. image:: https://img.shields.io/codecov/c/github/pyotp/pyotp/master.svg
@@ -128,11 +153,13 @@ Description: PyOTP - The Python One-Time Password Library
128
153
  Platform: MacOS X
129
154
  Platform: Posix
130
155
  Classifier: Intended Audience :: Developers
131
- Classifier: License :: OSI Approved :: BSD License
156
+ Classifier: License :: OSI Approved :: MIT License
132
157
  Classifier: Operating System :: MacOS :: MacOS X
133
158
  Classifier: Operating System :: POSIX
134
159
  Classifier: Programming Language :: Python
135
160
  Classifier: Programming Language :: Python :: 2.7
136
- Classifier: Programming Language :: Python :: 3.3
137
161
  Classifier: Programming Language :: Python :: 3.4
162
+ Classifier: Programming Language :: Python :: 3.5
163
+ Classifier: Programming Language :: Python :: 3.6
164
+ Classifier: Programming Language :: Python :: 3.7
138
165
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
@@ -261,6 +261,9 @@ class StringComparisonTest(CompareDigestTest):
261
261
  def test_fullwidth_input(self):
262
262
  self.assertTrue(self.method("xs12345", "xs12345"))
263
263
 
264
+ def test_unicode_equal(self):
265
+ self.assertTrue(self.method("ěšč45", "ěšč45"))
266
+
264
267
 
265
268
  class CounterOffsetTest(unittest.TestCase):
266
269
  def test_counter_offset(self):
File without changes
File without changes
File without changes
File without changes
File without changes