107 lines
3.3 KiB
Python
107 lines
3.3 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from typing import Literal
|
|
|
|
|
|
POSTBOX_PLAINTEXT_PROFILE = "plaintext_v1"
|
|
POSTBOX_MANAGED_ENVELOPE_PROFILE = "server_envelope_v1"
|
|
POSTBOX_EXTERNAL_E2EE_PROFILE = "external_e2ee_v1"
|
|
POSTBOX_LEGACY_EXTERNAL_ENVELOPE_PROFILE = "external_envelope_v1"
|
|
POSTBOX_STANDARD_PROFILE = POSTBOX_MANAGED_ENVELOPE_PROFILE
|
|
|
|
PostboxProtectionProfile = Literal[
|
|
"plaintext_v1",
|
|
"server_envelope_v1",
|
|
"external_e2ee_v1",
|
|
]
|
|
|
|
SUPPORTED_POSTBOX_PROTECTION_PROFILES = frozenset(
|
|
{
|
|
POSTBOX_PLAINTEXT_PROFILE,
|
|
POSTBOX_MANAGED_ENVELOPE_PROFILE,
|
|
POSTBOX_EXTERNAL_E2EE_PROFILE,
|
|
}
|
|
)
|
|
|
|
|
|
def normalize_postbox_protection_policy(
|
|
policy: dict[str, object] | None = None,
|
|
) -> dict[str, object]:
|
|
return {
|
|
"new_incumbent_history": "since_assignment",
|
|
"history_days": None,
|
|
"ordinary_rotation": "rewrap",
|
|
"compromise_rotation": "reencrypt",
|
|
"recovery_authority": "institutional_key_holders",
|
|
"recovery_quorum": 2,
|
|
"handover_authority": "dual_control",
|
|
"handover_quorum": 2,
|
|
"emergency_access": "dual_control",
|
|
"emergency_quorum": 2,
|
|
"export_authority": "dual_control",
|
|
"export_quorum": 2,
|
|
"destruction_authority": "dual_control",
|
|
"destruction_quorum": 2,
|
|
"external_recipient_assurance": "strong_identity",
|
|
"vacancy_escalation_content_access": "metadata_only",
|
|
**(policy or {}),
|
|
}
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class PostboxProtectionProfileDefinition:
|
|
id: PostboxProtectionProfile
|
|
label: str
|
|
description: str
|
|
server_can_decrypt: bool
|
|
requires_encryption_module: bool
|
|
requires_external_client: bool
|
|
standard: bool = False
|
|
|
|
|
|
POSTBOX_PROTECTION_PROFILE_DEFINITIONS = (
|
|
PostboxProtectionProfileDefinition(
|
|
id=POSTBOX_MANAGED_ENVELOPE_PROFILE,
|
|
label="Institution-managed envelope",
|
|
description=(
|
|
"The Encryption provider protects content and authorized institutional "
|
|
"key holders can govern recovery. This is the standard profile."
|
|
),
|
|
server_can_decrypt=True,
|
|
requires_encryption_module=True,
|
|
requires_external_client=False,
|
|
standard=True,
|
|
),
|
|
PostboxProtectionProfileDefinition(
|
|
id=POSTBOX_EXTERNAL_E2EE_PROFILE,
|
|
label="External end-to-end envelope",
|
|
description=(
|
|
"A reviewed client or producer supplies ciphertext, a signed manifest, "
|
|
"and recipient-wrapped keys. GovOPlaN stores and routes them but cannot "
|
|
"decrypt the content."
|
|
),
|
|
server_can_decrypt=False,
|
|
requires_encryption_module=False,
|
|
requires_external_client=True,
|
|
),
|
|
PostboxProtectionProfileDefinition(
|
|
id=POSTBOX_PLAINTEXT_PROFILE,
|
|
label="No application-layer encryption",
|
|
description=(
|
|
"Postbox stores readable message content. Transport and storage controls "
|
|
"may still apply, but this profile is not encrypted by Postbox."
|
|
),
|
|
server_can_decrypt=True,
|
|
requires_encryption_module=False,
|
|
requires_external_client=False,
|
|
),
|
|
)
|
|
|
|
|
|
def is_e2ee_profile(profile: str) -> bool:
|
|
return profile in {
|
|
POSTBOX_EXTERNAL_E2EE_PROFILE,
|
|
POSTBOX_LEGACY_EXTERNAL_ENVELOPE_PROFILE,
|
|
}
|