Mercurial > libervia-backend
comparison sat/memory/params.py @ 3160:330a5f1d9eea
core (memory/crypto): replaced `PyCrypto` by `cryptography`:
`PyCrypto` is unmaintained for years but was used in SàT for password hashing. This patch
fixes that by replacing `PyCrypto` by the reference `cryptography` module which is well
maintained.
The behaviour stays the same (except that previously async `hash`, `encrypt` and `decrypt`
methods are now synchronous, as they are quick and using a deferToThread may actually be
more resource intensive than using blocking methods).
It is planed to improve `memory.crypto` by using more up-to-date cryptography/hashing
algorithms in the future.
PyCrypto is no more a dependency of SàT
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 09 Feb 2020 23:50:26 +0100 |
parents | 559a625a236b |
children | 7d8a04a1d3a2 |
comparison
equal
deleted
inserted
replaced
3159:30e08d904208 | 3160:330a5f1d9eea |
---|---|
1 #!/usr/bin/env python3 | 1 #!/usr/bin/env python3 |
2 | 2 |
3 | 3 # SàT: a XMPP client |
4 # SAT: a jabber client | |
5 # Copyright (C) 2009-2020 Jérôme Poisson (goffi@goffi.org) | 4 # Copyright (C) 2009-2020 Jérôme Poisson (goffi@goffi.org) |
6 | 5 |
7 # This program is free software: you can redistribute it and/or modify | 6 # This program is free software: you can redistribute it and/or modify |
8 # it under the terms of the GNU Affero General Public License as published by | 7 # it under the terms of the GNU Affero General Public License as published by |
9 # the Free Software Foundation, either version 3 of the License, or | 8 # the Free Software Foundation, either version 3 of the License, or |
519 ) # profile password and empty passwords are returned "as is" | 518 ) # profile password and empty passwords are returned "as is" |
520 if not profile: | 519 if not profile: |
521 raise exceptions.ProfileNotSetError( | 520 raise exceptions.ProfileNotSetError( |
522 "The profile is needed to decrypt a password" | 521 "The profile is needed to decrypt a password" |
523 ) | 522 ) |
524 d = self.host.memory.decryptValue(value, profile) | 523 password = self.host.memory.decryptValue(value, profile) |
525 | 524 |
526 def gotPlainPassword(password): | 525 if password is None: |
527 if ( | 526 raise exceptions.InternalError("password should never be None") |
528 password is None | 527 return defer.succeed(password) |
529 ): # empty value means empty password, None means decryption failure | |
530 raise exceptions.InternalError( | |
531 _("The stored password could not be decrypted!") | |
532 ) | |
533 return password | |
534 | |
535 return d.addCallback(gotPlainPassword) | |
536 | 528 |
537 def _type_to_str(self, result): | 529 def _type_to_str(self, result): |
538 """Convert result to string, according to its type """ | 530 """Convert result to string, according to its type """ |
539 if isinstance(result, bool): | 531 if isinstance(result, bool): |
540 return C.boolConst(result) | 532 return C.boolConst(result) |
1054 ) | 1046 ) |
1055 d.addCallback( | 1047 d.addCallback( |
1056 lambda __: PasswordHasher.hash(value) | 1048 lambda __: PasswordHasher.hash(value) |
1057 ) # profile password is hashed (empty value stays empty) | 1049 ) # profile password is hashed (empty value stays empty) |
1058 elif value: # other non empty passwords are encrypted with the personal key | 1050 elif value: # other non empty passwords are encrypted with the personal key |
1059 d = BlockCipher.encrypt(personal_key, value) | 1051 d = defer.succeed(BlockCipher.encrypt(personal_key, value)) |
1060 else: | 1052 else: |
1061 d = defer.succeed(value) | 1053 d = defer.succeed(value) |
1062 else: | 1054 else: |
1063 d = defer.succeed(value) | 1055 d = defer.succeed(value) |
1064 | 1056 |