Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/jose/backends/native.py: 37%

41 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-06-07 06:16 +0000

1import hashlib 

2import hmac 

3import os 

4 

5from jose.backends.base import Key 

6from jose.constants import ALGORITHMS 

7from jose.exceptions import JWKError 

8from jose.utils import base64url_decode, base64url_encode 

9 

10 

11def get_random_bytes(num_bytes): 

12 return bytes(os.urandom(num_bytes)) 

13 

14 

15class HMACKey(Key): 

16 """ 

17 Performs signing and verification operations using HMAC 

18 and the specified hash function. 

19 """ 

20 

21 HASHES = {ALGORITHMS.HS256: hashlib.sha256, ALGORITHMS.HS384: hashlib.sha384, ALGORITHMS.HS512: hashlib.sha512} 

22 

23 def __init__(self, key, algorithm): 

24 if algorithm not in ALGORITHMS.HMAC: 

25 raise JWKError("hash_alg: %s is not a valid hash algorithm" % algorithm) 

26 self._algorithm = algorithm 

27 self._hash_alg = self.HASHES.get(algorithm) 

28 

29 if isinstance(key, dict): 

30 self.prepared_key = self._process_jwk(key) 

31 return 

32 

33 if not isinstance(key, str) and not isinstance(key, bytes): 

34 raise JWKError("Expecting a string- or bytes-formatted key.") 

35 

36 if isinstance(key, str): 

37 key = key.encode("utf-8") 

38 

39 invalid_strings = [ 

40 b"-----BEGIN PUBLIC KEY-----", 

41 b"-----BEGIN RSA PUBLIC KEY-----", 

42 b"-----BEGIN CERTIFICATE-----", 

43 b"ssh-rsa", 

44 ] 

45 

46 if any(string_value in key for string_value in invalid_strings): 

47 raise JWKError( 

48 "The specified key is an asymmetric key or x509 certificate and" 

49 " should not be used as an HMAC secret." 

50 ) 

51 

52 self.prepared_key = key 

53 

54 def _process_jwk(self, jwk_dict): 

55 if not jwk_dict.get("kty") == "oct": 

56 raise JWKError("Incorrect key type. Expected: 'oct', Received: %s" % jwk_dict.get("kty")) 

57 

58 k = jwk_dict.get("k") 

59 k = k.encode("utf-8") 

60 k = bytes(k) 

61 k = base64url_decode(k) 

62 

63 return k 

64 

65 def sign(self, msg): 

66 return hmac.new(self.prepared_key, msg, self._hash_alg).digest() 

67 

68 def verify(self, msg, sig): 

69 return hmac.compare_digest(sig, self.sign(msg)) 

70 

71 def to_dict(self): 

72 return { 

73 "alg": self._algorithm, 

74 "kty": "oct", 

75 "k": base64url_encode(self.prepared_key).decode("ASCII"), 

76 }