1111import threading
1212import syslog
1313import os
14+ import base64
1415from swsscommon .swsscommon import ConfigDBConnector
1516
1617class master_key_mgr :
@@ -54,7 +55,7 @@ def __write_passwd_file(self, feature_type, passwd):
5455 # Update the password for given feature
5556 lines [self ._feature_list .index (feature_type )] = feature_type + ' : ' + passwd + '\n '
5657
57- os .chmod (self ._file_path , 0o777 )
58+ os .chmod (self ._file_path , 0o640 )
5859 with open (self ._file_path , 'w' ) as file :
5960 file .writelines (lines )
6061 os .chmod (self ._file_path , 0o640 )
@@ -63,6 +64,7 @@ def __write_passwd_file(self, feature_type, passwd):
6364 except PermissionError :
6465 syslog .syslog (syslog .LOG_ERR , "__write_passwd_file: Read permission denied: {}" .format (self ._file_path ))
6566
67+
6668 # Read cipher pass file and return the feature specifc
6769 # password
6870 def __read_passwd_file (self , feature_type ):
@@ -87,29 +89,63 @@ def __read_passwd_file(self, feature_type):
8789
8890 return passwd
8991
90- # Encrypt the passkey
91- def encrypt_passkey (self , feature_type , secret , passwd ):
92- cmd = [ 'openssl' , 'enc' , '-aes-128-cbc' , '-A' , '-a' , '-salt' , '-pbkdf2' , '-pass' , 'pass:' + passwd ]
93- p = subprocess .Popen (cmd , stdin = subprocess .PIPE , stdout = subprocess .PIPE , stderr = subprocess .PIPE , universal_newlines = True )
94- outsecret , errs = p .communicate (input = secret )
95- if not errs :
92+
93+ def encrypt_passkey (self , feature_type , secret : str , passwd : str ) -> str :
94+ """
95+ Encrypts the plaintext using OpenSSL (AES-128-CBC, with salt and pbkdf2, no base64)
96+ and returns the result as a hex string.
97+ """
98+ cmd = [
99+ "openssl" , "enc" , "-aes-128-cbc" , "-salt" , "-pbkdf2" ,
100+ "-pass" , f"pass:{ passwd } "
101+ ]
102+ try :
103+ result = subprocess .run (
104+ cmd ,
105+ input = secret .encode (),
106+ stdout = subprocess .PIPE ,
107+ stderr = subprocess .PIPE ,
108+ check = True
109+ )
110+ encrypted_bytes = result .stdout
111+ b64_encoded = base64 .b64encode (encrypted_bytes ).decode ()
96112 self .__write_passwd_file (feature_type , passwd )
113+ return b64_encoded
114+ except subprocess .CalledProcessError as e :
115+ syslog .syslog (syslog .LOG_ERR , "encrypt_passkey: {} Encryption failed with ERR: {}" .format ((e )))
116+ return ""
97117
98- return outsecret ,errs
99118
100- # Decrypt the passkey
101- def decrypt_passkey (self , feature_type , secret ):
102- errs = "Passkey Decryption failed"
103- passwd = self .__read_passwd_file (feature_type )
104- if passwd is not None :
105- cmd = "echo " + format (secret ) + " | openssl enc -aes-128-cbc -a -d -salt -pbkdf2 -pass pass:" + passwd
106- proc = subprocess .Popen (cmd , shell = True , stdout = subprocess .PIPE )
107- output , errs = proc .communicate ()
119+ def decrypt_passkey (self , feature_type , b64_encoded : str ) -> str :
120+ """
121+ Decrypts a hex-encoded encrypted string using OpenSSL (AES-128-CBC, with salt and pbkdf2, no base64).
122+ Returns the decrypted plaintext.
123+ """
124+
125+ passwd = self .__read_passwd_file (feature_type ).strip ()
126+ if passwd is None :
127+ syslog .syslog (syslog .LOG_ERR , "decrypt_passkey: Enpty password for {} feature type" .format (feature_type ))
128+ return ""
108129
109- if not errs :
110- output = output .decode ('utf-8' )
130+ try :
131+ encrypted_bytes = base64 .b64decode (b64_encoded )
132+
133+ cmd = [
134+ "openssl" , "enc" , "-aes-128-cbc" , "-d" , "-salt" , "-pbkdf2" ,
135+ "-pass" , f"pass:{ passwd } "
136+ ]
137+ result = subprocess .run (
138+ cmd ,
139+ input = encrypted_bytes ,
140+ stdout = subprocess .PIPE ,
141+ stderr = subprocess .PIPE ,
142+ check = True
143+ )
144+ return result .stdout .decode ().strip ()
145+ except subprocess .CalledProcessError as e :
146+ syslog .syslog (syslog .LOG_ERR , "decrypt_passkey: Decryption failed with an ERR: {}" .format (e .stderr .decode ()))
147+ return ""
111148
112- return output , errs
113149
114150 # Check if the encryption is enabled
115151 def is_key_encrypt_enabled (self , table , entry ):
@@ -126,7 +162,7 @@ def del_cipher_pass(self, feature_type):
126162 Removes only the password for the given feature_type while keeping the file structure intact.
127163 """
128164 try :
129- os .chmod (self ._file_path , 0o777 )
165+ os .chmod (self ._file_path , 0o640 )
130166 with open (self ._file_path , "r" ) as file :
131167 lines = file .readlines ()
132168
@@ -145,3 +181,4 @@ def del_cipher_pass(self, feature_type):
145181
146182 except Exception as e :
147183 syslog .syslog (syslog .LOG_ERR , "del_cipher_pass: {} Exception occurred: {}" .format ((e )))
184+
0 commit comments