54 lines
1.5 KiB
Python
54 lines
1.5 KiB
Python
from typing import Any
|
|
from .model import JWSAlgModel, CompactSignature
|
|
from ..errors import (
|
|
DecodeError,
|
|
MissingAlgorithmError,
|
|
)
|
|
from ..util import (
|
|
json_b64encode,
|
|
json_b64decode,
|
|
urlsafe_b64encode,
|
|
urlsafe_b64decode,
|
|
)
|
|
|
|
__all__ = [
|
|
"sign_compact",
|
|
"verify_compact",
|
|
"detach_compact_content",
|
|
"decode_header",
|
|
]
|
|
|
|
|
|
def sign_compact(obj: CompactSignature, alg: JWSAlgModel, key: Any) -> bytes:
|
|
header_segment = json_b64encode(obj.headers())
|
|
payload_segment = urlsafe_b64encode(obj.payload)
|
|
signing_input = header_segment + b"." + payload_segment
|
|
signature = urlsafe_b64encode(alg.sign(signing_input, key))
|
|
return signing_input + b"." + signature
|
|
|
|
|
|
def verify_compact(obj: CompactSignature, alg: JWSAlgModel, key: Any) -> bool:
|
|
signing_input = obj.segments["header"] + b"." + obj.segments["payload"]
|
|
try:
|
|
sig = urlsafe_b64decode(obj.segments["signature"])
|
|
except (TypeError, ValueError):
|
|
return False
|
|
return alg.verify(signing_input, sig, key)
|
|
|
|
|
|
def detach_compact_content(value: str) -> str:
|
|
# https://www.rfc-editor.org/rfc/rfc7515#appendix-F
|
|
parts = value.split(".")
|
|
parts[1] = ""
|
|
return ".".join(parts)
|
|
|
|
|
|
def decode_header(header_segment: bytes) -> dict[str, Any]:
|
|
try:
|
|
protected: dict[str, Any] = json_b64decode(header_segment)
|
|
if "alg" not in protected:
|
|
raise MissingAlgorithmError()
|
|
except (TypeError, ValueError):
|
|
raise DecodeError("Invalid header")
|
|
return protected
|