mirror of
https://github.com/GAM-team/GAM.git
synced 2025-05-12 20:27:20 +00:00
473 lines
20 KiB
Python
473 lines
20 KiB
Python
"""passlib.tests.test_handlers_bcrypt - tests for passlib hash algorithms"""
|
|
#=============================================================================
|
|
# imports
|
|
#=============================================================================
|
|
from __future__ import with_statement
|
|
# core
|
|
import hashlib
|
|
import logging; log = logging.getLogger(__name__)
|
|
import os
|
|
import sys
|
|
import warnings
|
|
# site
|
|
# pkg
|
|
from passlib import hash
|
|
from passlib.utils import repeat_string
|
|
from passlib.utils.compat import irange, PY3, u, get_method_function
|
|
from passlib.tests.utils import TestCase, HandlerCase, skipUnless, \
|
|
TEST_MODE, b, catch_warnings, UserHandlerMixin, randintgauss, EncodingHandlerMixin
|
|
from passlib.tests.test_handlers import UPASS_WAV, UPASS_USD, UPASS_TABLE
|
|
# module
|
|
|
|
#=============================================================================
|
|
# bcrypt
|
|
#=============================================================================
|
|
class _bcrypt_test(HandlerCase):
|
|
"base for BCrypt test cases"
|
|
handler = hash.bcrypt
|
|
secret_size = 72
|
|
reduce_default_rounds = True
|
|
fuzz_salts_need_bcrypt_repair = True
|
|
|
|
known_correct_hashes = [
|
|
#
|
|
# from JTR 1.7.9
|
|
#
|
|
('U*U*U*U*', '$2a$05$c92SVSfjeiCD6F2nAD6y0uBpJDjdRkt0EgeC4/31Rf2LUZbDRDE.O'),
|
|
('U*U***U', '$2a$05$WY62Xk2TXZ7EvVDQ5fmjNu7b0GEzSzUXUh2cllxJwhtOeMtWV3Ujq'),
|
|
('U*U***U*', '$2a$05$Fa0iKV3E2SYVUlMknirWU.CFYGvJ67UwVKI1E2FP6XeLiZGcH3MJi'),
|
|
('*U*U*U*U', '$2a$05$.WRrXibc1zPgIdRXYfv.4uu6TD1KWf0VnHzq/0imhUhuxSxCyeBs2'),
|
|
('', '$2a$05$Otz9agnajgrAe0.kFVF9V.tzaStZ2s1s4ZWi/LY4sw2k/MTVFj/IO'),
|
|
|
|
#
|
|
# test vectors from http://www.openwall.com/crypt v1.2
|
|
# note that this omits any hashes that depend on crypt_blowfish's
|
|
# various CVE-2011-2483 workarounds (hash 2a and \xff\xff in password,
|
|
# and any 2x hashes); and only contain hashes which are correct
|
|
# under both crypt_blowfish 1.2 AND OpenBSD.
|
|
#
|
|
('U*U', '$2a$05$CCCCCCCCCCCCCCCCCCCCC.E5YPO9kmyuRGyh0XouQYb4YMJKvyOeW'),
|
|
('U*U*', '$2a$05$CCCCCCCCCCCCCCCCCCCCC.VGOzA784oUp/Z0DY336zx7pLYAy0lwK'),
|
|
('U*U*U', '$2a$05$XXXXXXXXXXXXXXXXXXXXXOAcXxm9kjPGEMsLznoKqmqw7tc8WCx4a'),
|
|
('', '$2a$05$CCCCCCCCCCCCCCCCCCCCC.7uG0VCzI2bS7j6ymqJi9CdcdxiRTWNy'),
|
|
('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
|
'0123456789chars after 72 are ignored',
|
|
'$2a$05$abcdefghijklmnopqrstuu5s2v8.iXieOjg/.AySBTTZIIVFJeBui'),
|
|
(b('\xa3'),
|
|
'$2a$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq'),
|
|
(b('\xff\xa3345'),
|
|
'$2a$05$/OK.fbVrR/bpIqNJ5ianF.nRht2l/HRhr6zmCp9vYUvvsqynflf9e'),
|
|
(b('\xa3ab'),
|
|
'$2a$05$/OK.fbVrR/bpIqNJ5ianF.6IflQkJytoRVc1yuaNtHfiuq.FRlSIS'),
|
|
(b('\xaa')*72 + b('chars after 72 are ignored as usual'),
|
|
'$2a$05$/OK.fbVrR/bpIqNJ5ianF.swQOIzjOiJ9GHEPuhEkvqrUyvWhEMx6'),
|
|
(b('\xaa\x55'*36),
|
|
'$2a$05$/OK.fbVrR/bpIqNJ5ianF.R9xrDjiycxMbQE2bp.vgqlYpW5wx2yy'),
|
|
(b('\x55\xaa\xff'*24),
|
|
'$2a$05$/OK.fbVrR/bpIqNJ5ianF.9tQZzcJfm3uj2NvJ/n5xkhpqLrMpWCe'),
|
|
|
|
# keeping one of their 2y tests, because we are supporting that.
|
|
(b('\xa3'),
|
|
'$2y$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq'),
|
|
|
|
#
|
|
# from py-bcrypt tests
|
|
#
|
|
('', '$2a$06$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s.'),
|
|
('a', '$2a$10$k87L/MF28Q673VKh8/cPi.SUl7MU/rWuSiIDDFayrKk/1tBsSQu4u'),
|
|
('abc', '$2a$10$WvvTPHKwdBJ3uk0Z37EMR.hLA2W6N9AEBhEgrAOljy2Ae5MtaSIUi'),
|
|
('abcdefghijklmnopqrstuvwxyz',
|
|
'$2a$10$fVH8e28OQRj9tqiDXs1e1uxpsjN0c7II7YPKXua2NAKYvM6iQk7dq'),
|
|
('~!@#$%^&*() ~!@#$%^&*()PNBFRD',
|
|
'$2a$10$LgfYWkbzEvQ4JakH7rOvHe0y8pHKF9OaFgwUZ2q7W2FFZmZzJYlfS'),
|
|
|
|
#
|
|
# custom test vectors
|
|
#
|
|
|
|
# ensures utf-8 used for unicode
|
|
(UPASS_TABLE,
|
|
'$2a$05$Z17AXnnlpzddNUvnC6cZNOSwMA/8oNiKnHTHTwLlBijfucQQlHjaG'),
|
|
]
|
|
|
|
if TEST_MODE("full"):
|
|
#
|
|
# add some extra tests related to 2/2a
|
|
#
|
|
CONFIG_2 = '$2$05$' + '.'*22
|
|
CONFIG_A = '$2a$05$' + '.'*22
|
|
known_correct_hashes.extend([
|
|
("", CONFIG_2 + 'J2ihDv8vVf7QZ9BsaRrKyqs2tkn55Yq'),
|
|
("", CONFIG_A + 'J2ihDv8vVf7QZ9BsaRrKyqs2tkn55Yq'),
|
|
("abc", CONFIG_2 + 'XuQjdH.wPVNUZ/bOfstdW/FqB8QSjte'),
|
|
("abc", CONFIG_A + 'ev6gDwpVye3oMCUpLY85aTpfBNHD0Ga'),
|
|
("abc"*23, CONFIG_2 + 'XuQjdH.wPVNUZ/bOfstdW/FqB8QSjte'),
|
|
("abc"*23, CONFIG_A + '2kIdfSj/4/R/Q6n847VTvc68BXiRYZC'),
|
|
("abc"*24, CONFIG_2 + 'XuQjdH.wPVNUZ/bOfstdW/FqB8QSjte'),
|
|
("abc"*24, CONFIG_A + 'XuQjdH.wPVNUZ/bOfstdW/FqB8QSjte'),
|
|
("abc"*24+'x', CONFIG_2 + 'XuQjdH.wPVNUZ/bOfstdW/FqB8QSjte'),
|
|
("abc"*24+'x', CONFIG_A + 'XuQjdH.wPVNUZ/bOfstdW/FqB8QSjte'),
|
|
])
|
|
|
|
known_correct_configs = [
|
|
('$2a$04$uM6csdM8R9SXTex/gbTaye', UPASS_TABLE,
|
|
'$2a$04$uM6csdM8R9SXTex/gbTayezuvzFEufYGd2uB6of7qScLjQ4GwcD4G'),
|
|
]
|
|
|
|
known_unidentified_hashes = [
|
|
# invalid minor version
|
|
"$2b$12$EXRkfkdmXnagzds2SSitu.MW9.gAVqa9eLS1//RYtYCmB1eLHg.9q",
|
|
"$2`$12$EXRkfkdmXnagzds2SSitu.MW9.gAVqa9eLS1//RYtYCmB1eLHg.9q",
|
|
]
|
|
|
|
known_malformed_hashes = [
|
|
# bad char in otherwise correct hash
|
|
# \/
|
|
"$2a$12$EXRkfkdmXn!gzds2SSitu.MW9.gAVqa9eLS1//RYtYCmB1eLHg.9q",
|
|
|
|
# unsupported (but recognized) minor version
|
|
"$2x$12$EXRkfkdmXnagzds2SSitu.MW9.gAVqa9eLS1//RYtYCmB1eLHg.9q",
|
|
|
|
# rounds not zero-padded (py-bcrypt rejects this, therefore so do we)
|
|
'$2a$6$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s.'
|
|
|
|
# NOTE: salts with padding bits set are technically malformed,
|
|
# but we can reliably correct & issue a warning for that.
|
|
]
|
|
|
|
platform_crypt_support = [
|
|
("freedbsd|openbsd|netbsd", True),
|
|
("darwin", False),
|
|
# linux - may be present via addon, e.g. debian's libpam-unix2
|
|
# solaris - depends on policy
|
|
]
|
|
|
|
#===================================================================
|
|
# override some methods
|
|
#===================================================================
|
|
def setUp(self):
|
|
# ensure builtin is enabled for duration of test.
|
|
if TEST_MODE("full") and self.backend == "builtin":
|
|
key = "PASSLIB_BUILTIN_BCRYPT"
|
|
orig = os.environ.get(key)
|
|
if orig:
|
|
self.addCleanup(os.environ.__setitem__, key, orig)
|
|
else:
|
|
self.addCleanup(os.environ.__delitem__, key)
|
|
os.environ[key] = "enabled"
|
|
super(_bcrypt_test, self).setUp()
|
|
|
|
def populate_settings(self, kwds):
|
|
# builtin is still just way too slow.
|
|
if self.backend == "builtin":
|
|
kwds.setdefault("rounds", 4)
|
|
super(_bcrypt_test, self).populate_settings(kwds)
|
|
|
|
#===================================================================
|
|
# fuzz testing
|
|
#===================================================================
|
|
def os_supports_ident(self, hash):
|
|
"check if OS crypt is expected to support given ident"
|
|
if hash is None:
|
|
return True
|
|
# most OSes won't support 2x/2y
|
|
# XXX: definitely not the BSDs, but what about the linux variants?
|
|
from passlib.handlers.bcrypt import IDENT_2X, IDENT_2Y
|
|
if hash.startswith(IDENT_2X) or hash.startswith(IDENT_2Y):
|
|
return False
|
|
return True
|
|
|
|
def fuzz_verifier_bcrypt(self):
|
|
# test against bcrypt, if available
|
|
from passlib.handlers.bcrypt import IDENT_2, IDENT_2A, IDENT_2X, IDENT_2Y
|
|
from passlib.utils import to_native_str, to_bytes
|
|
try:
|
|
import bcrypt
|
|
except ImportError:
|
|
return
|
|
if not hasattr(bcrypt, "_ffi"):
|
|
return
|
|
def check_bcrypt(secret, hash):
|
|
"bcrypt"
|
|
secret = to_bytes(secret, self.fuzz_password_encoding)
|
|
#if hash.startswith(IDENT_2Y):
|
|
# hash = IDENT_2A + hash[4:]
|
|
if hash.startswith(IDENT_2):
|
|
# bcryptor doesn't support $2$ hashes; but we can fake it
|
|
# using the $2a$ algorithm, by repeating the password until
|
|
# it's 72 chars in length.
|
|
hash = IDENT_2A + hash[3:]
|
|
if secret:
|
|
secret = repeat_string(secret, 72)
|
|
hash = to_bytes(hash)
|
|
try:
|
|
return bcrypt.hashpw(secret, hash) == hash
|
|
except ValueError:
|
|
raise ValueError("bcrypt rejected hash: %r" % (hash,))
|
|
return check_bcrypt
|
|
|
|
def fuzz_verifier_pybcrypt(self):
|
|
# test against py-bcrypt, if available
|
|
from passlib.handlers.bcrypt import IDENT_2, IDENT_2A, IDENT_2X, IDENT_2Y
|
|
from passlib.utils import to_native_str
|
|
try:
|
|
import bcrypt
|
|
except ImportError:
|
|
return
|
|
if hasattr(bcrypt, "_ffi"):
|
|
return
|
|
def check_pybcrypt(secret, hash):
|
|
"pybcrypt"
|
|
secret = to_native_str(secret, self.fuzz_password_encoding)
|
|
if hash.startswith(IDENT_2Y):
|
|
hash = IDENT_2A + hash[4:]
|
|
try:
|
|
return bcrypt.hashpw(secret, hash) == hash
|
|
except ValueError:
|
|
raise ValueError("py-bcrypt rejected hash: %r" % (hash,))
|
|
return check_pybcrypt
|
|
|
|
def fuzz_verifier_bcryptor(self):
|
|
# test against bcryptor, if available
|
|
from passlib.handlers.bcrypt import IDENT_2, IDENT_2A, IDENT_2Y
|
|
from passlib.utils import to_native_str
|
|
try:
|
|
from bcryptor.engine import Engine
|
|
except ImportError:
|
|
return
|
|
def check_bcryptor(secret, hash):
|
|
"bcryptor"
|
|
secret = to_native_str(secret, self.fuzz_password_encoding)
|
|
if hash.startswith(IDENT_2Y):
|
|
hash = IDENT_2A + hash[4:]
|
|
elif hash.startswith(IDENT_2):
|
|
# bcryptor doesn't support $2$ hashes; but we can fake it
|
|
# using the $2a$ algorithm, by repeating the password until
|
|
# it's 72 chars in length.
|
|
hash = IDENT_2A + hash[3:]
|
|
if secret:
|
|
secret = repeat_string(secret, 72)
|
|
return Engine(False).hash_key(secret, hash) == hash
|
|
return check_bcryptor
|
|
|
|
def get_fuzz_settings(self):
|
|
secret, other, kwds = super(_bcrypt_test,self).get_fuzz_settings()
|
|
from passlib.handlers.bcrypt import IDENT_2, IDENT_2X
|
|
from passlib.utils import to_bytes
|
|
ident = kwds.get('ident')
|
|
if ident == IDENT_2X:
|
|
# 2x is just recognized, not supported. don't test with it.
|
|
del kwds['ident']
|
|
elif ident == IDENT_2 and other and repeat_string(to_bytes(other), len(to_bytes(secret))) == to_bytes(secret):
|
|
# avoid false failure due to flaw in 0-revision bcrypt:
|
|
# repeated strings like 'abc' and 'abcabc' hash identically.
|
|
other = self.get_fuzz_password()
|
|
return secret, other, kwds
|
|
|
|
def fuzz_setting_rounds(self):
|
|
# decrease default rounds for fuzz testing to speed up volume.
|
|
return randintgauss(5, 8, 6, 1)
|
|
|
|
#===================================================================
|
|
# custom tests
|
|
#===================================================================
|
|
known_incorrect_padding = [
|
|
# password, bad hash, good hash
|
|
|
|
# 2 bits of salt padding set
|
|
# ("loppux", # \/
|
|
# "$2a$12$oaQbBqq8JnSM1NHRPQGXORm4GCUMqp7meTnkft4zgSnrbhoKdDV0C",
|
|
# "$2a$12$oaQbBqq8JnSM1NHRPQGXOOm4GCUMqp7meTnkft4zgSnrbhoKdDV0C"),
|
|
("test", # \/
|
|
'$2a$04$oaQbBqq8JnSM1NHRPQGXORY4Vw3bdHKLIXTecPDRAcJ98cz1ilveO',
|
|
'$2a$04$oaQbBqq8JnSM1NHRPQGXOOY4Vw3bdHKLIXTecPDRAcJ98cz1ilveO'),
|
|
|
|
# all 4 bits of salt padding set
|
|
# ("Passlib11", # \/
|
|
# "$2a$12$M8mKpW9a2vZ7PYhq/8eJVcUtKxpo6j0zAezu0G/HAMYgMkhPu4fLK",
|
|
# "$2a$12$M8mKpW9a2vZ7PYhq/8eJVOUtKxpo6j0zAezu0G/HAMYgMkhPu4fLK"),
|
|
("test", # \/
|
|
"$2a$04$yjDgE74RJkeqC0/1NheSScrvKeu9IbKDpcQf/Ox3qsrRS/Kw42qIS",
|
|
"$2a$04$yjDgE74RJkeqC0/1NheSSOrvKeu9IbKDpcQf/Ox3qsrRS/Kw42qIS"),
|
|
|
|
# bad checksum padding
|
|
("test", # \/
|
|
"$2a$04$yjDgE74RJkeqC0/1NheSSOrvKeu9IbKDpcQf/Ox3qsrRS/Kw42qIV",
|
|
"$2a$04$yjDgE74RJkeqC0/1NheSSOrvKeu9IbKDpcQf/Ox3qsrRS/Kw42qIS"),
|
|
]
|
|
|
|
def test_90_bcrypt_padding(self):
|
|
"test passlib correctly handles bcrypt padding bits"
|
|
self.require_TEST_MODE("full")
|
|
#
|
|
# prevents reccurrence of issue 25 (https://code.google.com/p/passlib/issues/detail?id=25)
|
|
# were some unused bits were incorrectly set in bcrypt salt strings.
|
|
# (fixed since 1.5.3)
|
|
#
|
|
bcrypt = self.handler
|
|
corr_desc = ".*incorrectly set padding bits"
|
|
|
|
#
|
|
# test encrypt() / genconfig() don't generate invalid salts anymore
|
|
#
|
|
def check_padding(hash):
|
|
assert hash.startswith("$2a$") and len(hash) >= 28
|
|
self.assertTrue(hash[28] in '.Oeu',
|
|
"unused bits incorrectly set in hash: %r" % (hash,))
|
|
for i in irange(6):
|
|
check_padding(bcrypt.genconfig())
|
|
for i in irange(3):
|
|
check_padding(bcrypt.encrypt("bob", rounds=bcrypt.min_rounds))
|
|
|
|
#
|
|
# test genconfig() corrects invalid salts & issues warning.
|
|
#
|
|
with self.assertWarningList(["salt too large", corr_desc]):
|
|
hash = bcrypt.genconfig(salt="."*21 + "A.", rounds=5, relaxed=True)
|
|
self.assertEqual(hash, "$2a$05$" + "." * 22)
|
|
|
|
#
|
|
# make sure genhash() corrects input
|
|
#
|
|
samples = self.known_incorrect_padding
|
|
for pwd, bad, good in samples:
|
|
with self.assertWarningList([corr_desc]):
|
|
self.assertEqual(bcrypt.genhash(pwd, bad), good)
|
|
with self.assertWarningList([]):
|
|
self.assertEqual(bcrypt.genhash(pwd, good), good)
|
|
|
|
#
|
|
# and that verify() works good & bad
|
|
#
|
|
with self.assertWarningList([corr_desc]):
|
|
self.assertTrue(bcrypt.verify(pwd, bad))
|
|
with self.assertWarningList([]):
|
|
self.assertTrue(bcrypt.verify(pwd, good))
|
|
|
|
#
|
|
# test normhash cleans things up correctly
|
|
#
|
|
for pwd, bad, good in samples:
|
|
with self.assertWarningList([corr_desc]):
|
|
self.assertEqual(bcrypt.normhash(bad), good)
|
|
with self.assertWarningList([]):
|
|
self.assertEqual(bcrypt.normhash(good), good)
|
|
self.assertEqual(bcrypt.normhash("$md5$abc"), "$md5$abc")
|
|
|
|
hash.bcrypt._no_backends_msg() # call this for coverage purposes
|
|
|
|
# create test cases for specific backends
|
|
bcrypt_bcrypt_test, bcrypt_pybcrypt_test, bcrypt_bcryptor_test, bcrypt_os_crypt_test, bcrypt_builtin_test = \
|
|
_bcrypt_test.create_backend_cases(["bcrypt", "pybcrypt", "bcryptor", "os_crypt", "builtin"])
|
|
|
|
#=============================================================================
|
|
# bcrypt
|
|
#=============================================================================
|
|
class _bcrypt_sha256_test(HandlerCase):
|
|
"base for BCrypt-SHA256 test cases"
|
|
handler = hash.bcrypt_sha256
|
|
reduce_default_rounds = True
|
|
forbidden_characters = None
|
|
fuzz_salts_need_bcrypt_repair = True
|
|
fallback_os_crypt_handler = hash.bcrypt
|
|
|
|
known_correct_hashes = [
|
|
#
|
|
# custom test vectors
|
|
#
|
|
|
|
# empty
|
|
("",
|
|
'$bcrypt-sha256$2a,5$E/e/2AOhqM5W/KJTFQzLce$F6dYSxOdAEoJZO2eoHUZWZljW/e0TXO'),
|
|
|
|
# ascii
|
|
("password",
|
|
'$bcrypt-sha256$2a,5$5Hg1DKFqPE8C2aflZ5vVoe$12BjNE0p7axMg55.Y/mHsYiVuFBDQyu'),
|
|
|
|
# unicode / utf8
|
|
(UPASS_TABLE,
|
|
'$bcrypt-sha256$2a,5$.US1fQ4TQS.ZTz/uJ5Kyn.$QNdPDOTKKT5/sovNz1iWg26quOU4Pje'),
|
|
(UPASS_TABLE.encode("utf-8"),
|
|
'$bcrypt-sha256$2a,5$.US1fQ4TQS.ZTz/uJ5Kyn.$QNdPDOTKKT5/sovNz1iWg26quOU4Pje'),
|
|
|
|
# test >72 chars is hashed correctly -- under bcrypt these hash the same.
|
|
# NOTE: test_60_secret_size() handles this already, this is just for overkill :)
|
|
(repeat_string("abc123",72),
|
|
'$bcrypt-sha256$2a,5$X1g1nh3g0v4h6970O68cxe$r/hyEtqJ0teqPEmfTLoZ83ciAI1Q74.'),
|
|
(repeat_string("abc123",72)+"qwr",
|
|
'$bcrypt-sha256$2a,5$X1g1nh3g0v4h6970O68cxe$021KLEif6epjot5yoxk0m8I0929ohEa'),
|
|
(repeat_string("abc123",72)+"xyz",
|
|
'$bcrypt-sha256$2a,5$X1g1nh3g0v4h6970O68cxe$7.1kgpHduMGEjvM3fX6e/QCvfn6OKja'),
|
|
]
|
|
|
|
known_correct_configs =[
|
|
('$bcrypt-sha256$2a,5$5Hg1DKFqPE8C2aflZ5vVoe',
|
|
"password", '$bcrypt-sha256$2a,5$5Hg1DKFqPE8C2aflZ5vVoe$12BjNE0p7axMg55.Y/mHsYiVuFBDQyu'),
|
|
]
|
|
|
|
known_malformed_hashes = [
|
|
# bad char in otherwise correct hash
|
|
# \/
|
|
'$bcrypt-sha256$2a,5$5Hg1DKF!PE8C2aflZ5vVoe$12BjNE0p7axMg55.Y/mHsYiVuFBDQyu',
|
|
|
|
# unrecognized bcrypt variant
|
|
'$bcrypt-sha256$2c,5$5Hg1DKFqPE8C2aflZ5vVoe$12BjNE0p7axMg55.Y/mHsYiVuFBDQyu',
|
|
|
|
# unsupported bcrypt variant
|
|
'$bcrypt-sha256$2x,5$5Hg1DKFqPE8C2aflZ5vVoe$12BjNE0p7axMg55.Y/mHsYiVuFBDQyu',
|
|
|
|
# rounds zero-padded
|
|
'$bcrypt-sha256$2a,05$5Hg1DKFqPE8C2aflZ5vVoe$12BjNE0p7axMg55.Y/mHsYiVuFBDQyu',
|
|
|
|
# config string w/ $ added
|
|
'$bcrypt-sha256$2a,5$5Hg1DKFqPE8C2aflZ5vVoe$',
|
|
]
|
|
|
|
#===================================================================
|
|
# override some methods -- cloned from bcrypt
|
|
#===================================================================
|
|
def setUp(self):
|
|
# ensure builtin is enabled for duration of test.
|
|
if TEST_MODE("full") and self.backend == "builtin":
|
|
key = "PASSLIB_BUILTIN_BCRYPT"
|
|
orig = os.environ.get(key)
|
|
if orig:
|
|
self.addCleanup(os.environ.__setitem__, key, orig)
|
|
else:
|
|
self.addCleanup(os.environ.__delitem__, key)
|
|
os.environ[key] = "enabled"
|
|
super(_bcrypt_sha256_test, self).setUp()
|
|
|
|
def populate_settings(self, kwds):
|
|
# builtin is still just way too slow.
|
|
if self.backend == "builtin":
|
|
kwds.setdefault("rounds", 4)
|
|
super(_bcrypt_sha256_test, self).populate_settings(kwds)
|
|
|
|
#===================================================================
|
|
# override ident tests for now
|
|
#===================================================================
|
|
def test_30_HasManyIdents(self):
|
|
raise self.skipTest("multiple idents not supported")
|
|
|
|
def test_30_HasOneIdent(self):
|
|
# forbidding ident keyword, we only support "2a" for now
|
|
handler = self.handler
|
|
handler(use_defaults=True)
|
|
self.assertRaises(ValueError, handler, ident="$2y$", use_defaults=True)
|
|
|
|
#===================================================================
|
|
# fuzz testing -- cloned from bcrypt
|
|
#===================================================================
|
|
def fuzz_setting_rounds(self):
|
|
# decrease default rounds for fuzz testing to speed up volume.
|
|
return randintgauss(5, 8, 6, 1)
|
|
|
|
# create test cases for specific backends
|
|
bcrypt_sha256_bcrypt_test, bcrypt_sha256_pybcrypt_test, bcrypt_sha256_bcryptor_test, bcrypt_sha256_os_crypt_test, bcrypt_sha256_builtin_test = \
|
|
_bcrypt_sha256_test.create_backend_cases(["bcrypt", "pybcrypt", "bcryptor", "os_crypt", "builtin"])
|
|
|
|
#=============================================================================
|
|
# eof
|
|
#=============================================================================
|