Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented OS keyring storage for credential file password #434

Draft
wants to merge 1 commit into
base: development
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 23 additions & 5 deletions utils/encryption.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import getpass as getpass
import stdiomask
import getpass
import json
import os
from base64 import b64encode, b64decode

import keyring
import stdiomask
from Crypto.Cipher import ChaCha20_Poly1305
from Crypto.Random import get_random_bytes
from Crypto.Protocol.KDF import scrypt
from Crypto.Random import get_random_bytes
from keyring.errors import PasswordDeleteError

from utils.logger import log

KEYRING_SERVICE_NAME = "fairgame"


def encrypt(pt, password):
"""Encryption function to securely store user credentials, uses ChaCha_Poly1305
Expand Down Expand Up @@ -52,6 +56,14 @@ def create_encrypted_config(data, file_path):
cpass = stdiomask.getpass(prompt="Credential file password: ", mask="*")
vpass = stdiomask.getpass(prompt="Verify credential file password: ", mask="*")
if cpass == vpass:
# Clear any previous key:
try:
keyring.delete_password(KEYRING_SERVICE_NAME, getpass.getuser())
except PasswordDeleteError:
# Assume the password didn't exist?
pass
# Store the password in the system keyring service
keyring.set_password(KEYRING_SERVICE_NAME, getpass.getuser(), cpass)
result = encrypt(payload, cpass)
with open(file_path, "w") as f:
f.write(result)
Expand All @@ -69,7 +81,13 @@ def load_encrypted_config(config_path):
data = json_file.read()
try:
if "nonce" in data:
password = stdiomask.getpass(prompt="Credential file password: ", mask="*")
# Retrieve the password from the system keyring service
password = keyring.get_password(KEYRING_SERVICE_NAME, getpass.getuser())
if not password:
# legacy mode for people who upgrade without recreating the file
password = stdiomask.getpass(
prompt="Credential file password: ", mask="*"
)
decrypted = decrypt(data, password)
return json.loads(decrypted)
else:
Expand Down