synta 0.3.1

ASN.1 parser, decoder, and encoder library with DER/BER support and C FFI
Documentation
"""
synta.acme — RFC 8737 ACME TLS-ALPN-01 extension types.

Provides :class:`AcmeAuthorization` for the ``id-pe-acmeIdentifier`` extension
(OID ``1.3.6.1.5.5.7.1.31``) used during ACME TLS-ALPN-01 domain validation.

The extension value is a 32-byte SHA-256 digest of the ACME key authorization
string::

    key_authorization = token + "." + base64url(SHA-256(accountKey JWK))
    digest = SHA-256(key_authorization.encode("ascii"))

The OID is also available as :data:`synta.oids.PE_ACME_IDENTIFIER`.
"""

from __future__ import annotations

from synta import ObjectIdentifier

# ── AcmeAuthorization ─────────────────────────────────────────────────────────

class AcmeAuthorization:
    """ACME TLS-ALPN-01 authorization digest (RFC 8737 §3).

    Wraps the 32-byte SHA-256 digest placed in the ``id-pe-acmeIdentifier``
    X.509 extension (OID ``1.3.6.1.5.5.7.1.31``) of an ACME TLS-ALPN-01
    validation certificate.  The extension MUST be marked critical.

    Example::

        import synta
        import synta.acme as acme

        digest = synta.digest("sha256", b"token.thumbprint")
        auth = acme.AcmeAuthorization(digest)
        print(auth.hex_digest)          # 64-character lowercase hex
        der = auth.to_der()             # 34 bytes: 04 20 <digest>
        auth2 = acme.AcmeAuthorization.from_der(der)
        assert auth == auth2
    """

    def __new__(cls, digest: bytes) -> AcmeAuthorization:
        """Construct an ``AcmeAuthorization`` from 32 raw digest bytes.

        :param digest: exactly 32 bytes (SHA-256 output).
        :raises ValueError: if ``digest`` is not exactly 32 bytes.
        """
        ...

    @staticmethod
    def from_der(data: bytes) -> AcmeAuthorization:
        """Parse a DER-encoded ``Authorization`` OCTET STRING.

        Accepts exactly 34 bytes: tag ``0x04``, length ``0x20``, then the
        32-byte digest.  Trailing bytes are rejected.

        :param data: exactly 34-byte DER buffer.
        :raises ValueError: if the data cannot be decoded, has the wrong
            length, or contains trailing bytes.
        """
        ...

    def to_der(self) -> bytes:
        """Return the DER encoding of this ``Authorization`` value.

        The encoding is the OCTET STRING TLV: ``04 20 <32 bytes>``.

        :returns: ``bytes`` of length 34.
        """
        ...

    @property
    def digest(self) -> bytes:
        """The raw 32-byte SHA-256 digest.

        Equivalent to ``bytes(auth)`` via :meth:`__bytes__`.
        """
        ...

    @property
    def hex_digest(self) -> str:
        """Lowercase hexadecimal representation of the 32-byte digest (64 characters)."""
        ...

    def __bytes__(self) -> bytes:
        """Return the raw 32-byte digest as :class:`bytes`."""
        ...

    def __repr__(self) -> str: ...
    def __eq__(self, other: object) -> bool: ...
    def __hash__(self) -> int: ...
    def __len__(self) -> int: ...

# ── OID constants ─────────────────────────────────────────────────────────────

ID_PE_ACME_IDENTIFIER: ObjectIdentifier
"""``id-pe-acmeIdentifier`` (1.3.6.1.5.5.7.1.31, RFC 8737 §3).

OID for the ACME TLS-ALPN-01 domain validation extension.  The extension
MUST be marked critical.  Also available as ``synta.oids.PE_ACME_IDENTIFIER``.
"""