Support text string services names in Vault internal API
Marco Ricci

Marco Ricci commited on 2024-09-01 14:55:36
Zeige 1 geänderte Dateien mit 18 Einfügungen und 15 Löschungen.

... ...
@@ -89,7 +89,8 @@ class Vault:
89 89
         Args:
90 90
             phrase:
91 91
                 The master passphrase from which to derive the service
92
-                passphrases.
92
+                passphrases.  If a string, then the UTF-8 encoding of
93
+                the string is used.
93 94
             length:
94 95
                 Desired passphrase length.
95 96
             repeat:
... ...
@@ -239,7 +240,7 @@ class Vault:
239 240
     def create_hash(
240 241
         cls,
241 242
         phrase: bytes | bytearray | str,
242
-        service: bytes | bytearray,
243
+        service: bytes | bytearray | str,
243 244
         *,
244 245
         length: int = 32,
245 246
     ) -> bytes:
... ...
@@ -253,11 +254,13 @@ class Vault:
253 254
             phrase:
254 255
                 A master passphrase, or sometimes an SSH signature.
255 256
                 Used as the key for PBKDF2, the underlying cryptographic
256
-                primitive.
257
+                primitive.  If a string, then the UTF-8 encoding of the
258
+                string is used.
257 259
             service:
258 260
                 A vault service name.  Will be suffixed with
259 261
                 `Vault._UUID`, and then used as the salt value for
260
-                PBKDF2.
262
+                PBKDF2.  If a string, then the UTF-8 encoding of the
263
+                string is used.
261 264
             length:
262 265
                 The length of the byte stream to generate.
263 266
 
... ...
@@ -282,7 +285,7 @@ class Vault:
282 285
             ... 0d 08 1f ec f8 73 9b 8c 5f 55 39 16 7c 53 54 2c
283 286
             ... 1e 52 bb 30 ed 7f 89 e2 2f 69 51 55 d8 9e a6 02
284 287
             ... ''')
285
-            >>> Vault.create_hash(phrase, b'some_service', length=4)
288
+            >>> Vault.create_hash(phrase, 'some_service', length=4)
286 289
             b'M\xb1<S'
287 290
             >>> Vault.create_hash(phrase, b'some_service', length=16)
288 291
             b'M\xb1<S\x827E\xd1M\xaf\xf8~\xc8n\x10\xcc'
... ...
@@ -292,7 +295,7 @@ class Vault:
292 295
         """
293 296
         phrase = cls._get_binary_string(phrase)
294 297
         assert not isinstance(phrase, str)
295
-        salt = bytes(service) + cls._UUID
298
+        salt = cls._get_binary_string(service) + cls._UUID
296 299
         return hashlib.pbkdf2_hmac(
297 300
             hash_name='sha1',
298 301
             password=phrase,
... ...
@@ -303,7 +306,7 @@ class Vault:
303 306
 
304 307
     def generate(
305 308
         self,
306
-        service_name: str | bytes | bytearray,
309
+        service_name: bytes | bytearray | str,
307 310
         /,
308 311
         *,
309 312
         phrase: bytes | bytearray | str = b'',
... ...
@@ -312,10 +315,12 @@ class Vault:
312 315
 
313 316
         Args:
314 317
             service_name:
315
-                The service name.
318
+                The service name.  If a string, then the UTF-8 encoding
319
+                of the string is used.
316 320
             phrase:
317 321
                 If given, override the passphrase given during
318
-                construction.
322
+                construction.  If a string, then the UTF-8 encoding of
323
+                the string is used.
319 324
 
320 325
         Returns:
321 326
             The service passphrase.
... ...
@@ -332,16 +337,14 @@ class Vault:
332 337
         """
333 338
         hash_length = self._estimate_sufficient_hash_length()
334 339
         assert hash_length >= 1
335
-        # Ensure the phrase is a bytes object.  Needed later for safe
336
-        # concatenation.
337
-        if isinstance(service_name, str):
338
-            service_name = service_name.encode('utf-8')
339
-        elif not isinstance(service_name, bytes):
340
-            service_name = bytes(service_name)
340
+        # Ensure the phrase and the service name are bytes objects.
341
+        # This is needed later for safe concatenation.
342
+        service_name = self._get_binary_string(service_name)
341 343
         assert_type(service_name, bytes)
342 344
         if not phrase:
343 345
             phrase = self._phrase
344 346
         phrase = self._get_binary_string(phrase)
347
+        assert_type(phrase, bytes)
345 348
         # Repeat the passphrase generation with ever-increasing hash
346 349
         # lengths, until the passphrase can be formed without exhausting
347 350
         # the sequin.  See the guarantee in the create_hash method for
348 351