@@ -45,9 +45,9 @@ def scramble_native_password(password, message):
4545
4646def scramble_caching_sha2 (password , nonce ):
4747 """Scramble algorithm used in cached_sha2_password fast path.
48-
48+
4949 XOR(SHA256(password), SHA256(SHA256(SHA256(password)), nonce))
50-
50+
5151 Note: This uses SHA256 as specified by the MySQL protocol RFC, not for
5252 secure password storage. This is a challenge-response mechanism where
5353 the actual password verification is done server-side with proper
@@ -58,7 +58,7 @@ def scramble_caching_sha2(password, nonce):
5858
5959 # MySQL protocol specified SHA256 usage - not for password storage
6060 p1 = hashlib .sha256 (password ).digest () # nosec B324
61- p2 = hashlib .sha256 (p1 ).digest () # nosec B324
61+ p2 = hashlib .sha256 (p1 ).digest () # nosec B324
6262 p3 = hashlib .sha256 (p2 + nonce ).digest () # nosec B324
6363
6464 res = bytearray (p1 )
@@ -83,14 +83,14 @@ def _parse_pem_public_key(pem_data):
8383 """Parse PEM public key and extract RSA parameters"""
8484 if isinstance (pem_data , str ):
8585 pem_data = pem_data .encode ('ascii' )
86-
86+
8787 # Remove PEM headers/footers and decode base64
8888 import base64
8989 lines = pem_data .strip ().split (b'\n ' )
90- key_data = b'' .join (line for line in lines
91- if not line .startswith (b'-----' ))
90+ key_data = b'' .join (line for line in lines
91+ if not line .startswith (b'-----' ))
9292 der_data = base64 .b64decode (key_data )
93-
93+
9494 # Parse DER-encoded public key (simplified ASN.1 parsing)
9595 # This is a basic implementation for MySQL's RSA keys
9696 try :
@@ -104,21 +104,21 @@ def _parse_der_public_key(der_data):
104104 """Parse DER-encoded RSA public key"""
105105 # Very basic ASN.1 parsing for RSA public keys
106106 # Format: SEQUENCE { modulus INTEGER, publicExponent INTEGER }
107-
107+
108108 pos = 0
109-
109+
110110 # Skip SEQUENCE tag and length
111111 if der_data [pos ] != 0x30 : # SEQUENCE tag
112112 raise ValueError ("Invalid DER format" )
113113 pos += 1
114-
114+
115115 # Skip length bytes
116116 length_byte = der_data [pos ]
117117 pos += 1
118118 if length_byte & 0x80 :
119119 length_bytes = length_byte & 0x7f
120120 pos += length_bytes
121-
121+
122122 # Skip algorithm identifier sequence (if present)
123123 if der_data [pos ] == 0x30 :
124124 pos += 1
@@ -129,7 +129,7 @@ def _parse_der_public_key(der_data):
129129 pos += length_bytes
130130 else :
131131 pos += alg_len
132-
132+
133133 # Skip BIT STRING tag and length for public key
134134 if der_data [pos ] == 0x03 : # BIT STRING
135135 pos += 1
@@ -139,24 +139,24 @@ def _parse_der_public_key(der_data):
139139 length_bytes = bit_len & 0x7f
140140 pos += length_bytes
141141 pos += 1 # Skip unused bits byte
142-
142+
143143 # Parse the actual RSA key
144144 if der_data [pos ] != 0x30 : # SEQUENCE for RSA key
145145 raise ValueError ("Invalid RSA key format" )
146146 pos += 1
147-
147+
148148 # Skip sequence length
149149 seq_len = der_data [pos ]
150150 pos += 1
151151 if seq_len & 0x80 :
152152 length_bytes = seq_len & 0x7f
153153 pos += length_bytes
154-
154+
155155 # Parse modulus (n)
156156 if der_data [pos ] != 0x02 : # INTEGER tag
157157 raise ValueError ("Expected modulus integer" )
158158 pos += 1
159-
159+
160160 mod_len = der_data [pos ]
161161 pos += 1
162162 if mod_len & 0x80 :
@@ -165,20 +165,20 @@ def _parse_der_public_key(der_data):
165165 for i in range (length_bytes ):
166166 mod_len = (mod_len << 8 ) | der_data [pos ]
167167 pos += 1
168-
168+
169169 # Skip leading zero if present
170170 if der_data [pos ] == 0x00 :
171171 pos += 1
172172 mod_len -= 1
173-
173+
174174 modulus = _bytes_to_int (der_data [pos :pos + mod_len ])
175175 pos += mod_len
176-
176+
177177 # Parse exponent (e)
178178 if der_data [pos ] != 0x02 : # INTEGER tag
179179 raise ValueError ("Expected exponent integer" )
180180 pos += 1
181-
181+
182182 exp_len = der_data [pos ]
183183 pos += 1
184184 if exp_len & 0x80 :
@@ -187,26 +187,26 @@ def _parse_der_public_key(der_data):
187187 for i in range (length_bytes ):
188188 exp_len = (exp_len << 8 ) | der_data [pos ]
189189 pos += 1
190-
190+
191191 exponent = _bytes_to_int (der_data [pos :pos + exp_len ])
192-
192+
193193 return modulus , exponent
194194
195195
196196def _extract_rsa_params_fallback (der_data ):
197197 """Fallback method to extract RSA parameters"""
198198 # This is a more permissive parser for various key formats
199-
199+
200200 # Look for INTEGER sequences (modulus and exponent)
201201 integers = []
202202 pos = 0
203-
203+
204204 while pos < len (der_data ) - 3 :
205205 if der_data [pos ] == 0x02 : # INTEGER tag
206206 pos += 1
207207 length = der_data [pos ]
208208 pos += 1
209-
209+
210210 if length & 0x80 :
211211 length_bytes = length & 0x7f
212212 if length_bytes > 4 or pos + length_bytes >= len (der_data ):
@@ -216,75 +216,75 @@ def _extract_rsa_params_fallback(der_data):
216216 for i in range (length_bytes ):
217217 length = (length << 8 ) | der_data [pos ]
218218 pos += 1
219-
219+
220220 if length > 0 and pos + length <= len (der_data ):
221221 # Skip leading zero
222222 start_pos = pos
223223 if der_data [pos ] == 0x00 and length > 1 :
224224 start_pos += 1
225225 length -= 1
226-
227- if length > 16 : # Reasonable size for RSA components (lowered threshold)
226+
227+ if length > 16 : # Reasonable size for RSA components
228228 value = _bytes_to_int (der_data [start_pos :start_pos + length ])
229229 integers .append (value )
230- # Also check for common exponents
230+ # Also check for common exponents
231231 elif length <= 8 and length > 0 : # Could be exponent
232232 value = _bytes_to_int (der_data [start_pos :start_pos + length ])
233233 if value in (3 , 17 , 65537 ): # Common RSA exponents
234234 integers .append (value )
235-
235+
236236 pos += length
237237 else :
238238 pos += 1
239239 else :
240240 pos += 1
241-
241+
242242 if len (integers ) >= 2 :
243243 # Find modulus (largest) and exponent (common values)
244244 modulus = max (integers )
245245 exponent = 65537 # Default
246-
246+
247247 for i in integers :
248248 if i != modulus and i in (3 , 17 , 65537 ):
249249 exponent = i
250250 break
251-
251+
252252 return modulus , exponent
253-
253+
254254 raise ValueError ("Could not extract RSA parameters" )
255255
256256
257257def _pkcs1_pad (message , key_size ):
258258 """Apply PKCS#1 v1.5 padding for encryption"""
259259 # PKCS#1 v1.5 padding format: 0x00 || 0x02 || PS || 0x00 || M
260260 # where PS is random non-zero padding bytes
261-
261+
262262 import os
263-
263+
264264 message_len = len (message )
265265 padded_len = (key_size + 7 ) // 8 # Key size in bytes
266-
266+
267267 if message_len > padded_len - 11 :
268268 raise ValueError ("Message too long for key size" )
269-
269+
270270 padding_len = padded_len - message_len - 3
271-
271+
272272 # Generate random non-zero padding with better entropy
273273 padding = bytearray ()
274274 attempts = 0
275275 max_attempts = padding_len * 10
276-
276+
277277 while len (padding ) < padding_len and attempts < max_attempts :
278278 rand_bytes = os .urandom (min (256 , padding_len - len (padding )))
279279 for b in rand_bytes :
280280 if b != 0 and len (padding ) < padding_len :
281281 padding .append (b )
282282 attempts += 1
283-
283+
284284 # If we couldn't generate enough random bytes, fill with safe non-zero values
285285 while len (padding ) < padding_len :
286286 padding .append (0xFF )
287-
287+
288288 padded = bytes ([0x00 , 0x02 ]) + bytes (padding ) + bytes ([0x00 ]) + message
289289 return padded
290290
@@ -298,30 +298,30 @@ def _rsa_encrypt_native(message, modulus, exponent):
298298 """Encrypt message using RSA with native Python implementation"""
299299 # Determine key size in bits
300300 key_size = modulus .bit_length ()
301-
301+
302302 # Apply PKCS#1 v1.5 padding
303303 padded_message = _pkcs1_pad (message , key_size )
304-
304+
305305 # Convert to integer
306306 message_int = _bytes_to_int (padded_message )
307-
307+
308308 # Perform RSA encryption: c = m^e mod n
309309 ciphertext_int = _mod_exp (message_int , exponent , modulus )
310-
310+
311311 # Convert back to bytes
312312 ciphertext_len = (key_size + 7 ) // 8
313313 return _int_to_bytes (ciphertext_int , ciphertext_len )
314314
315315
316316def sha2_rsa_encrypt_native (password , salt , public_key ):
317317 """Encrypt password with salt and public key using native Python.
318-
318+
319319 Used for sha256_password and caching_sha2_password.
320320 """
321321 message = _xor_password (password + b"\0 " , salt )
322-
322+
323323 # Parse the PEM public key
324324 modulus , exponent = _parse_pem_public_key (public_key )
325-
325+
326326 # Encrypt using native RSA implementation
327- return _rsa_encrypt_native (message , modulus , exponent )
327+ return _rsa_encrypt_native (message , modulus , exponent )
0 commit comments