76 lines
2.2 KiB
Python
76 lines
2.2 KiB
Python
from .models import CompactEncryption, Recipient
|
|
from .registry import JWERegistry
|
|
from .._keys import Key
|
|
from ..errors import (
|
|
MissingAlgorithmError,
|
|
MissingEncryptionError,
|
|
DecodeError,
|
|
)
|
|
from ..util import (
|
|
json_b64decode,
|
|
urlsafe_b64encode,
|
|
urlsafe_b64decode,
|
|
)
|
|
|
|
__all__ = [
|
|
"represent_compact",
|
|
"extract_compact",
|
|
]
|
|
|
|
|
|
def represent_compact(obj: CompactEncryption) -> bytes:
|
|
assert obj.recipient is not None
|
|
encrypted_key = obj.recipient.encrypted_key
|
|
assert encrypted_key is not None
|
|
return b".".join(
|
|
[
|
|
obj.base64_segments["aad"],
|
|
urlsafe_b64encode(encrypted_key),
|
|
obj.base64_segments["iv"],
|
|
obj.base64_segments["ciphertext"],
|
|
obj.base64_segments["tag"],
|
|
]
|
|
)
|
|
|
|
|
|
def extract_compact(value: bytes, registry: JWERegistry) -> CompactEncryption:
|
|
parts = value.split(b".")
|
|
if len(parts) != 5:
|
|
raise ValueError("Invalid JSON Web Encryption")
|
|
|
|
header_segment, ek_segment, iv_segment, ciphertext_segment, tag_segment = parts
|
|
registry.validate_protected_header_size(header_segment)
|
|
registry.validate_encrypted_key_size(ek_segment)
|
|
registry.validate_initialization_vector_size(iv_segment)
|
|
registry.validate_ciphertext_size(ciphertext_segment)
|
|
registry.validate_auth_tag_size(tag_segment)
|
|
try:
|
|
protected = json_b64decode(header_segment)
|
|
if "alg" not in protected:
|
|
raise MissingAlgorithmError()
|
|
if "enc" not in protected:
|
|
raise MissingEncryptionError()
|
|
except (TypeError, ValueError):
|
|
raise DecodeError("Invalid header")
|
|
|
|
obj = CompactEncryption(protected)
|
|
obj.base64_segments.update(
|
|
{
|
|
"aad": header_segment,
|
|
"iv": iv_segment,
|
|
"ciphertext": ciphertext_segment,
|
|
"tag": tag_segment,
|
|
}
|
|
)
|
|
obj.bytes_segments.update(
|
|
{
|
|
"iv": urlsafe_b64decode(iv_segment),
|
|
"ciphertext": urlsafe_b64decode(ciphertext_segment),
|
|
"tag": urlsafe_b64decode(tag_segment),
|
|
}
|
|
)
|
|
recipient: Recipient[Key] = Recipient(obj)
|
|
recipient.encrypted_key = urlsafe_b64decode(ek_segment)
|
|
obj.recipient = recipient
|
|
return obj
|