Skip to content
Open
Show file tree
Hide file tree
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
48 changes: 31 additions & 17 deletions src/lib/Config.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,24 @@


class Config:
"""
Configuration manager for the vault application.

# Config file location
config_path = None
Handles reading, writing, and managing vault configuration settings
including encryption salts, TTL settings, and version information.
"""

# Config
config = configparser.ConfigParser()
def __init__(self, config_path: str):
"""
Initialize Config with a path to the configuration file.

def __init__(self, config_path):
Args:
config_path: Path to the configuration file
"""
self.config_path = config_path
# BUG FIX: Moved from class-level to instance-level to prevent
# shared mutable state between Config instances
self.config = configparser.ConfigParser()

def get_config(self):
"""
Expand All @@ -29,19 +38,20 @@ def get_config(self):

def set_default_config_file(self):
"""
Set a user default config file
"""
Set a user default configuration file with initial settings.

self.config['MAIN'] = {
'version': '2.00',
'keyVersion': '1', # Will be used to support legacy key versions
# if the algorithm changes
'salt': self.generate_random_salt(),
'clipboardTTL': '15',
'hideSecretTTL': '5',
'autoLockTTL': '900',
'encryptedDb': True,
}
Creates a new config file with default values for version, salt,
and TTL settings.
"""
# Set each config value individually to avoid type issues
self.config['MAIN'] = {}
self.config['MAIN']['version'] = '2.00'
self.config['MAIN']['keyVersion'] = '1'
self.config['MAIN']['salt'] = self.generate_random_salt()
self.config['MAIN']['clipboardTTL'] = '15'
self.config['MAIN']['hideSecretTTL'] = '5'
self.config['MAIN']['autoLockTTL'] = '900'
self.config['MAIN']['encryptedDb'] = 'True'

# Save
self.save_config()
Expand All @@ -51,6 +61,10 @@ def update(self, name, value):
Update a config value
"""

# Ensure config is initialized (MAIN section exists)
if 'MAIN' not in self.config:
self.get_config()

# Set new value
self.config['MAIN'][name] = str(value)

Expand Down
26 changes: 21 additions & 5 deletions src/lib/Encryption.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,17 @@ def encrypt(self, secret):

def decrypt(self, enc_secret):
"""
Decrypt a secret
"""
Decrypt a secret.

Args:
enc_secret: Base64-encoded encrypted secret

Returns:
Decrypted secret as bytes

Raises:
ValueError: If padding is invalid (indicates tampering or wrong key)
"""
# Decode base 64
enc_secret = base64.b64decode(enc_secret)

Expand All @@ -102,12 +110,20 @@ def decrypt(self, enc_secret):
# Decrypt
data = aes.decrypt(enc_secret[AES.block_size:])

# pick the padding value from the end; Python 2.x: ord(data[-1])
# pick the padding value from the end
# BUG FIX: Enhanced padding validation
if not data:
raise ValueError("Empty data after decryption")

padding = data[-1]

# Python 2.x: chr(padding) * padding
# Validate padding value is in range
if padding < 1 or padding > AES.block_size:
raise ValueError("Invalid padding value")

# Validate all padding bytes match
if data[-padding:] != bytes([padding]) * padding:
raise ValueError("Invalid padding...")
raise ValueError("Invalid padding - data may be corrupted or key is wrong")

# Reset salted key
self.set_salt()
Expand Down
Loading