forked from s3lph/matemat
Merge branch '3-constant-time-password-verification' into 'master'
Resolve "Password verification apparently vulnerable to timing attacks" Closes #3 See merge request s3lph/matemat!11
This commit is contained in:
commit
b12535bc93
1 changed files with 7 additions and 4 deletions
|
@ -2,6 +2,7 @@
|
||||||
from typing import List, Optional, Any, Type
|
from typing import List, Optional, Any, Type
|
||||||
|
|
||||||
import crypt
|
import crypt
|
||||||
|
from hmac import compare_digest
|
||||||
|
|
||||||
from matemat.primitives import User, Product
|
from matemat.primitives import User, Product
|
||||||
from matemat.exceptions import AuthenticationError, DatabaseConsistencyError
|
from matemat.exceptions import AuthenticationError, DatabaseConsistencyError
|
||||||
|
@ -144,9 +145,11 @@ class MatematDatabase(object):
|
||||||
if row is None:
|
if row is None:
|
||||||
raise AuthenticationError('User does not exist')
|
raise AuthenticationError('User does not exist')
|
||||||
user_id, username, email, pwhash, tkhash, admin, member = row
|
user_id, username, email, pwhash, tkhash, admin, member = row
|
||||||
if password is not None and crypt.crypt(password, pwhash) != pwhash:
|
if password is not None and not compare_digest(crypt.crypt(password, pwhash), pwhash):
|
||||||
raise AuthenticationError('Password mismatch')
|
raise AuthenticationError('Password mismatch')
|
||||||
elif touchkey is not None and tkhash is not None and crypt.crypt(touchkey, tkhash) != tkhash:
|
elif touchkey is not None \
|
||||||
|
and tkhash is not None \
|
||||||
|
and not compare_digest(crypt.crypt(touchkey, tkhash), tkhash):
|
||||||
raise AuthenticationError('Touchkey mismatch')
|
raise AuthenticationError('Touchkey mismatch')
|
||||||
elif touchkey is not None and tkhash is None:
|
elif touchkey is not None and tkhash is None:
|
||||||
raise AuthenticationError('Touchkey not set')
|
raise AuthenticationError('Touchkey not set')
|
||||||
|
@ -171,7 +174,7 @@ class MatematDatabase(object):
|
||||||
if row is None:
|
if row is None:
|
||||||
raise AuthenticationError('User does not exist in database.')
|
raise AuthenticationError('User does not exist in database.')
|
||||||
# Verify the old password, if it should be verified.
|
# Verify the old password, if it should be verified.
|
||||||
if verify_password and crypt.crypt(oldpass, row[0]) != row[0]:
|
if verify_password and not compare_digest(crypt.crypt(oldpass, row[0]), row[0]):
|
||||||
raise AuthenticationError('Old password does not match.')
|
raise AuthenticationError('Old password does not match.')
|
||||||
# Hash the new password and write it to the database.
|
# Hash the new password and write it to the database.
|
||||||
pwhash: str = crypt.crypt(newpass, crypt.mksalt(_CRYPT_METHOD))
|
pwhash: str = crypt.crypt(newpass, crypt.mksalt(_CRYPT_METHOD))
|
||||||
|
@ -201,7 +204,7 @@ class MatematDatabase(object):
|
||||||
if row is None:
|
if row is None:
|
||||||
raise AuthenticationError('User does not exist in database.')
|
raise AuthenticationError('User does not exist in database.')
|
||||||
# Verify the password, if it should be verified.
|
# Verify the password, if it should be verified.
|
||||||
if verify_password and crypt.crypt(password, row[0]) != row[0]:
|
if verify_password and not compare_digest(crypt.crypt(password, row[0]), row[0]):
|
||||||
raise AuthenticationError('Password does not match.')
|
raise AuthenticationError('Password does not match.')
|
||||||
# Hash the new touchkey and write it to the database.
|
# Hash the new touchkey and write it to the database.
|
||||||
tkhash: str = crypt.crypt(touchkey, crypt.mksalt(_CRYPT_METHOD)) if touchkey is not None else None
|
tkhash: str = crypt.crypt(touchkey, crypt.mksalt(_CRYPT_METHOD)) if touchkey is not None else None
|
||||||
|
|
Loading…
Reference in a new issue