core (memory): Modernize methods signature/docstrings of encrypt_value and decrypt_value:
- Use `client` instead of `profile` - Add `decrypt_value_by_profile` which is notably useful on client startup, when the encrypted password needs to be retrieved, and the `SatXMPPEntity` instance is not yet created. - Add type hints/update docstrings rel 477
This commit is contained in:
parent
e0064e0372
commit
ed462a661b
3 changed files with 48 additions and 33 deletions
|
|
@ -1105,45 +1105,59 @@ class Memory:
|
|||
|
||||
## Encryption ##
|
||||
|
||||
def encrypt_value(self, value, profile):
|
||||
"""Encrypt a value for the given profile. The personal key must be loaded
|
||||
already in the profile session, that should be the case if the profile is
|
||||
already authenticated.
|
||||
def encrypt_value(self, client: SatXMPPEntity, value: str) -> str:
|
||||
"""Encrypt a value for the given profile.
|
||||
|
||||
@param value (str): the value to encrypt
|
||||
@param profile (str): %(doc_profile)s
|
||||
@return: the deferred encrypted value
|
||||
I uses a personal key derived from password. The personal key is stable on profile
|
||||
password change, so there is no need to re-encrypt.
|
||||
|
||||
The personal key must be loaded already in the profile session, that should be the
|
||||
case if the profile is already authenticated (session started).
|
||||
|
||||
@param client: client instance.
|
||||
Its profile's personal key will be used as encryption key.
|
||||
@param value: the value to encrypt
|
||||
@return: base-64 encoded encrypted value
|
||||
"""
|
||||
try:
|
||||
personal_key = self.auth_sessions.profile_get_unique(profile)[
|
||||
C.MEMORY_CRYPTO_KEY
|
||||
]
|
||||
except TypeError:
|
||||
session = self.auth_sessions.profile_get_unique(client.profile)
|
||||
if session is None or (personal_key := session.get(C.MEMORY_CRYPTO_KEY)) is None:
|
||||
raise exceptions.InternalError(
|
||||
_("Trying to encrypt a value for %s while the personal key is undefined!")
|
||||
% profile
|
||||
f"Trying to encrypt a value for {client.profile} while the personal key "
|
||||
"is undefined!"
|
||||
)
|
||||
return BlockCipher.encrypt(personal_key, value)
|
||||
|
||||
def decrypt_value(self, value, profile):
|
||||
"""Decrypt a value for the given profile. The personal key must be loaded
|
||||
already in the profile session, that should be the case if the profile is
|
||||
already authenticated.
|
||||
def decrypt_value(self, client: SatXMPPEntity, encrypted: str) -> str:
|
||||
"""Decrypt a value for the given profile.
|
||||
|
||||
@param value (str): the value to decrypt
|
||||
@param profile (str): %(doc_profile)s
|
||||
@return: the deferred decrypted value
|
||||
See [encrypt_value].
|
||||
|
||||
@param client: client instance.
|
||||
Its profile's personal key will be used as encryption key.
|
||||
@param encrypted: base-64 encoded encrypted value
|
||||
@return: decrypted value
|
||||
@raise exceptions.InternalError: personal key is not loaded
|
||||
"""
|
||||
try:
|
||||
personal_key = self.auth_sessions.profile_get_unique(profile)[
|
||||
C.MEMORY_CRYPTO_KEY
|
||||
]
|
||||
except TypeError:
|
||||
return self.decrypt_value_by_profile(encrypted, client.profile)
|
||||
|
||||
def decrypt_value_by_profile(self, encrypted: str, profile: str) -> str:
|
||||
"""Decrypt a value for the given profile by its name.
|
||||
|
||||
Useful when a client is not yet available, but the profile session has been
|
||||
started.
|
||||
|
||||
@param encrypted: base-64 encoded encrypted value
|
||||
@param profile: profile name
|
||||
@return: decrypted value
|
||||
@raise exceptions.InternalError: personal key is not loaded
|
||||
"""
|
||||
session = self.auth_sessions.profile_get_unique(profile)
|
||||
if session is None or (personal_key := session.get(C.MEMORY_CRYPTO_KEY)) is None:
|
||||
raise exceptions.InternalError(
|
||||
_("Trying to decrypt a value for %s while the personal key is undefined!")
|
||||
% profile
|
||||
f"Trying to decrypt a value for {profile} while the personal key "
|
||||
"is undefined!"
|
||||
)
|
||||
return BlockCipher.decrypt(personal_key, value)
|
||||
return BlockCipher.decrypt(personal_key, encrypted)
|
||||
|
||||
def encrypt_personal_data(self, data_key, data_value, crypto_key, profile):
|
||||
"""Re-encrypt a personal data (saved to a PersistentDict).
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from libervia.backend import G
|
||||
from libervia.backend.core.i18n import _, D_
|
||||
|
||||
from libervia.backend.core import exceptions
|
||||
|
|
@ -515,7 +516,7 @@ class Params(object):
|
|||
raise exceptions.ProfileNotSetError(
|
||||
"The profile is needed to decrypt a password"
|
||||
)
|
||||
password = self.host.memory.decrypt_value(value, profile)
|
||||
password = self.host.memory.decrypt_value_by_profile(value, profile)
|
||||
|
||||
if password is None:
|
||||
raise exceptions.InternalError("password should never be None")
|
||||
|
|
|
|||
|
|
@ -248,7 +248,7 @@ class Account(potr.context.Account):
|
|||
if self.privkey is None:
|
||||
raise exceptions.InternalError(_("Save is called but privkey is None !"))
|
||||
priv_key = hexlify(self.privkey.serializePrivateKey())
|
||||
encrypted_priv_key = self.host.memory.encrypt_value(priv_key, self.client.profile)
|
||||
encrypted_priv_key = self.host.memory.encrypt_value(self.client, priv_key)
|
||||
self.client._otr_data[PRIVATE_KEY] = encrypted_priv_key
|
||||
|
||||
def load_trusts(self):
|
||||
|
|
@ -373,7 +373,7 @@ class OTR(object):
|
|||
yield client._otr_data.load()
|
||||
encrypted_priv_key = client._otr_data.get(PRIVATE_KEY, None)
|
||||
if encrypted_priv_key is not None:
|
||||
priv_key = self.host.memory.decrypt_value(encrypted_priv_key, client.profile)
|
||||
priv_key = self.host.memory.decrypt_value(client, encrypted_priv_key)
|
||||
ctxMng.account.privkey = potr.crypt.PK.parsePrivateKey(
|
||||
unhexlify(priv_key.encode("utf-8"))
|
||||
)[0]
|
||||
|
|
|
|||
Loading…
Reference in a new issue