Source code for acme.jws

"""ACME-specific JWS.

The JWS implementation in josepy only implements the base JOSE standard. In
order to support the new header fields defined in ACME, this module defines some
ACME-specific classes that layer on top of josepy.
"""
from typing import Optional

import josepy as jose






[docs] class Signature(jose.Signature): """ACME-specific Signature. Uses ACME-specific Header for customer fields.""" __slots__ = jose.Signature._orig_slots # pylint: disable=protected-access,no-member # TODO: decoder/encoder should accept cls? Otherwise, subclassing # JSONObjectWithFields is tricky... header_cls = Header header: Header = jose.field( 'header', omitempty=True, default=header_cls(), decoder=header_cls.from_json)
# TODO: decoder should check that nonce is in the protected header
[docs] class JWS(jose.JWS): """ACME-specific JWS. Includes none, url, and kid in protected header.""" signature_cls = Signature __slots__ = jose.JWS._orig_slots # pylint: disable=protected-access
[docs] @classmethod # type: ignore[override] # pylint: disable=arguments-differ def sign(cls, payload: bytes, key: jose.JWK, alg: jose.JWASignature, nonce: Optional[bytes], url: Optional[str] = None, kid: Optional[str] = None) -> jose.JWS: # Per ACME spec, jwk and kid are mutually exclusive, so only include a # jwk field if kid is not provided. include_jwk = kid is None return super().sign(payload, key=key, alg=alg, protect=frozenset(['nonce', 'url', 'kid', 'jwk', 'alg']), nonce=nonce, url=url, kid=kid, include_jwk=include_jwk)