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
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-07 06:16 +0000
1import hashlib
2import hmac
3import os
5from jose.backends.base import Key
6from jose.constants import ALGORITHMS
7from jose.exceptions import JWKError
8from jose.utils import base64url_decode, base64url_encode
11def get_random_bytes(num_bytes):
12 return bytes(os.urandom(num_bytes))
15class HMACKey(Key):
16 """
17 Performs signing and verification operations using HMAC
18 and the specified hash function.
19 """
21 HASHES = {ALGORITHMS.HS256: hashlib.sha256, ALGORITHMS.HS384: hashlib.sha384, ALGORITHMS.HS512: hashlib.sha512}
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)
29 if isinstance(key, dict):
30 self.prepared_key = self._process_jwk(key)
31 return
33 if not isinstance(key, str) and not isinstance(key, bytes):
34 raise JWKError("Expecting a string- or bytes-formatted key.")
36 if isinstance(key, str):
37 key = key.encode("utf-8")
39 invalid_strings = [
40 b"-----BEGIN PUBLIC KEY-----",
41 b"-----BEGIN RSA PUBLIC KEY-----",
42 b"-----BEGIN CERTIFICATE-----",
43 b"ssh-rsa",
44 ]
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 )
52 self.prepared_key = key
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"))
58 k = jwk_dict.get("k")
59 k = k.encode("utf-8")
60 k = bytes(k)
61 k = base64url_decode(k)
63 return k
65 def sign(self, msg):
66 return hmac.new(self.prepared_key, msg, self._hash_alg).digest()
68 def verify(self, msg, sig):
69 return hmac.compare_digest(sig, self.sign(msg))
71 def to_dict(self):
72 return {
73 "alg": self._algorithm,
74 "kty": "oct",
75 "k": base64url_encode(self.prepared_key).decode("ASCII"),
76 }