diff options
| author | Stephen Rosen <sirosen@globus.org> | 2022-11-02 06:01:52 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-11-02 17:01:52 +0600 |
| commit | 00cd759d86aae24176ead7bdbed273a07532443e (patch) | |
| tree | 34f5fd7e5d0c55299fc5c8685fb558aeebaf9f4a /tests | |
| parent | 345549567dbb58fd7bf901392cf6b1a626f36e24 (diff) | |
| download | pyjwt-00cd759d86aae24176ead7bdbed273a07532443e.tar.gz | |
Add `Algorithm.compute_hash_digest` and use it to implement at_hash validation example (#775)
* Add compute_hash_digest to Algorithm objects
`Algorithm.compute_hash_digest` is defined as a method which inspects
the object to see that it has the requisite attributes, `hash_alg`.
If `hash_alg` is not set, then the method raises a
NotImplementedError. This applies to classes like NoneAlgorithm.
If `hash_alg` is set, then it is checked for
```
has_crypto # is cryptography available?
and isinstance(hash_alg, type)
and issubclass(hash_alg, hashes.HashAlgorithm)
```
to see which API for computing a digest is appropriate --
`hashlib` vs `cryptography.hazmat.primitives.hashes`.
These checks could be avoided at runtime if it were necessary to
optimize further (e.g. attach compute_hash_digest methods to classes
with a class decorator) but this is not clearly a worthwhile
optimization. Such perf tuning is intentionally omitted for now.
* Add doc example of OIDC login flow
The goal of this doc example is to demonstrate usage of
`get_algorithm_by_name` and `compute_hash_digest` for the purpose of
`at_hash` validation. It is not meant to be a "guaranteed correct" and
spec-compliant example.
closes #314
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test_algorithms.py | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/tests/test_algorithms.py b/tests/test_algorithms.py index 538078a..894ce28 100644 --- a/tests/test_algorithms.py +++ b/tests/test_algorithms.py @@ -45,6 +45,12 @@ class TestAlgorithms: with pytest.raises(NotImplementedError): algo.to_jwk("value") + def test_algorithm_should_throw_exception_if_compute_hash_digest_not_impl(self): + algo = Algorithm() + + with pytest.raises(NotImplementedError): + algo.compute_hash_digest(b"value") + def test_none_algorithm_should_throw_exception_if_key_is_not_none(self): algo = NoneAlgorithm() @@ -1054,3 +1060,20 @@ class TestOKPAlgorithms: signature_2 = algo.sign(b"Hello World!", priv_key_2) assert algo.verify(b"Hello World!", pub_key_2, signature_1) assert algo.verify(b"Hello World!", pub_key_2, signature_2) + + @crypto_required + def test_rsa_can_compute_digest(self): + # this is the well-known sha256 hash of "foo" + foo_hash = base64.b64decode(b"LCa0a2j/xo/5m0U8HTBBNBNCLXBkg7+g+YpeiGJm564=") + + algo = RSAAlgorithm(RSAAlgorithm.SHA256) + computed_hash = algo.compute_hash_digest(b"foo") + assert computed_hash == foo_hash + + def test_hmac_can_compute_digest(self): + # this is the well-known sha256 hash of "foo" + foo_hash = base64.b64decode(b"LCa0a2j/xo/5m0U8HTBBNBNCLXBkg7+g+YpeiGJm564=") + + algo = HMACAlgorithm(HMACAlgorithm.SHA256) + computed_hash = algo.compute_hash_digest(b"foo") + assert computed_hash == foo_hash |
