Files
Shadowbroker/backend/services/mesh/mesh_wormhole_contacts.py
T
2026-05-01 22:56:50 -06:00

1791 lines
81 KiB
Python

"""Wormhole-owned DM contact and alias graph state."""
from __future__ import annotations
import time
from pathlib import Path
from typing import Any
from services.mesh.mesh_secure_storage import read_secure_json, write_secure_json
DATA_DIR = Path(__file__).resolve().parents[2] / "data"
CONTACTS_FILE = DATA_DIR / "wormhole_dm_contacts.json"
TRUST_LEVELS = (
"unpinned",
"tofu_pinned",
"invite_pinned",
"sas_verified",
"mismatch",
"continuity_broken",
)
VERIFIED_FIRST_CONTACT_TRUST_LEVELS = (
"invite_pinned",
"sas_verified",
)
TRUST_RECOMMENDED_ACTIONS = {
"unpinned": "import_invite",
"tofu_pinned": "verify_sas",
"invite_pinned": "show_sas",
"sas_verified": "show_sas",
"mismatch": "reverify",
"continuity_broken": "reverify",
}
def _default_contact() -> dict[str, Any]:
return {
"alias": "",
"blocked": False,
"dhPubKey": "",
"dhAlgo": "",
"sharedAlias": "",
"sharedAliasCounter": 0,
"sharedAliasPublicKey": "",
"sharedAliasPublicKeyAlgo": "Ed25519",
"dmIdentityId": "",
"previousSharedAliases": [],
"pendingSharedAlias": "",
"pendingSharedAliasCounter": 0,
"pendingSharedAliasPublicKey": "",
"pendingSharedAliasPublicKeyAlgo": "Ed25519",
"pendingSharedAliasGraceMs": 0,
"sharedAliasGraceUntil": 0,
"sharedAliasRotatedAt": 0,
"acceptedPreviousAlias": "",
"acceptedPreviousAliasCounter": 0,
"acceptedPreviousAliasPublicKey": "",
"acceptedPreviousAliasPublicKeyAlgo": "Ed25519",
"acceptedPreviousGraceUntil": 0,
"acceptedPreviousHardGraceUntil": 0,
"acceptedPreviousAwaitingReply": False,
"aliasBindingSeq": 0,
"aliasBindingPendingReason": "",
"aliasBindingPreparedAt": 0,
"aliasGateJoinAppliedSeq": 0,
"trust_level": "unpinned",
"verify_inband": False,
"verify_registry": False,
"verified": False,
"verify_mismatch": False,
"verified_at": 0,
"invitePinnedTrustFingerprint": "",
"invitePinnedNodeId": "",
"invitePinnedPublicKey": "",
"invitePinnedPublicKeyAlgo": "",
"invitePinnedDhPubKey": "",
"invitePinnedDhAlgo": "",
"invitePinnedPrekeyLookupHandle": "",
"invitePinnedRootFingerprint": "",
"invitePinnedRootManifestFingerprint": "",
"invitePinnedRootWitnessPolicyFingerprint": "",
"invitePinnedRootWitnessThreshold": 0,
"invitePinnedRootWitnessCount": 0,
"invitePinnedRootWitnessDomainCount": 0,
"invitePinnedRootManifestGeneration": 0,
"invitePinnedRootRotationProven": False,
"invitePinnedRootNodeId": "",
"invitePinnedRootPublicKey": "",
"invitePinnedRootPublicKeyAlgo": "",
"invitePinnedIssuedAt": 0,
"invitePinnedExpiresAt": 0,
"invitePinnedAt": 0,
"remotePrekeyFingerprint": "",
"remotePrekeyObservedFingerprint": "",
"remotePrekeyRootFingerprint": "",
"remotePrekeyRootManifestFingerprint": "",
"remotePrekeyRootWitnessPolicyFingerprint": "",
"remotePrekeyRootWitnessThreshold": 0,
"remotePrekeyRootWitnessCount": 0,
"remotePrekeyRootWitnessDomainCount": 0,
"remotePrekeyRootManifestGeneration": 0,
"remotePrekeyRootRotationProven": False,
"remotePrekeyObservedRootFingerprint": "",
"remotePrekeyObservedRootManifestFingerprint": "",
"remotePrekeyObservedRootWitnessPolicyFingerprint": "",
"remotePrekeyObservedRootWitnessThreshold": 0,
"remotePrekeyObservedRootWitnessCount": 0,
"remotePrekeyObservedRootWitnessDomainCount": 0,
"remotePrekeyObservedRootManifestGeneration": 0,
"remotePrekeyObservedRootRotationProven": False,
"remotePrekeyRootNodeId": "",
"remotePrekeyRootPublicKey": "",
"remotePrekeyRootPublicKeyAlgo": "",
"remotePrekeyRootPinnedAt": 0,
"remotePrekeyRootLastSeenAt": 0,
"remotePrekeyRootMismatch": False,
"remotePrekeyPinnedAt": 0,
"remotePrekeyLastSeenAt": 0,
"remotePrekeySequence": 0,
"remotePrekeySignedAt": 0,
"remotePrekeyMismatch": False,
"remotePrekeyTransparencyHead": "",
"remotePrekeyTransparencySize": 0,
"remotePrekeyTransparencySeenAt": 0,
"remotePrekeyTransparencyConflict": False,
"remotePrekeyLookupMode": "",
"witness_count": 0,
"witness_checked_at": 0,
"vouch_count": 0,
"vouch_checked_at": 0,
"updated_at": 0,
}
CLIENT_MUTABLE_CONTACT_FIELDS = frozenset(
{
"alias",
"blocked",
"dhPubKey",
"dhAlgo",
"sharedAlias",
"sharedAliasCounter",
"sharedAliasPublicKey",
"sharedAliasPublicKeyAlgo",
"previousSharedAliases",
"pendingSharedAlias",
"pendingSharedAliasCounter",
"pendingSharedAliasPublicKey",
"pendingSharedAliasPublicKeyAlgo",
"pendingSharedAliasGraceMs",
"sharedAliasGraceUntil",
"sharedAliasRotatedAt",
"acceptedPreviousAlias",
"acceptedPreviousAliasCounter",
"acceptedPreviousAliasPublicKey",
"acceptedPreviousAliasPublicKeyAlgo",
"acceptedPreviousGraceUntil",
"acceptedPreviousHardGraceUntil",
"acceptedPreviousAwaitingReply",
"aliasBindingSeq",
"aliasBindingPendingReason",
"aliasBindingPreparedAt",
"aliasGateJoinAppliedSeq",
"verify_mismatch",
"remotePrekeyTransparencyHead",
"remotePrekeyTransparencySize",
"remotePrekeyTransparencySeenAt",
"remotePrekeyTransparencyConflict",
"remotePrekeyLookupMode",
"witness_count",
"witness_checked_at",
"vouch_count",
"vouch_checked_at",
}
)
def _sanitize_client_contact_updates(updates: dict[str, Any] | None) -> dict[str, Any]:
current = dict(updates or {})
sanitized: dict[str, Any] = {}
for key in CLIENT_MUTABLE_CONTACT_FIELDS:
if key in current:
sanitized[key] = current[key]
return sanitized
def _contact_root_rotation_view(current: dict[str, Any]) -> tuple[int, bool]:
root_mismatch = bool(current.get("remotePrekeyRootMismatch"))
if root_mismatch:
generation = int(current.get("remotePrekeyObservedRootManifestGeneration", 0) or 0)
if generation <= 0:
generation = int(current.get("remotePrekeyRootManifestGeneration", 0) or 0)
if generation <= 0:
return 0, False
return generation, generation <= 1 or bool(current.get("remotePrekeyObservedRootRotationProven"))
generation = int(current.get("remotePrekeyRootManifestGeneration", 0) or 0)
proven = bool(current.get("remotePrekeyRootRotationProven"))
if generation <= 0:
generation = int(current.get("invitePinnedRootManifestGeneration", 0) or 0)
proven = bool(current.get("invitePinnedRootRotationProven"))
if generation <= 0:
return 0, False
return generation, generation <= 1 or proven
def _contact_root_witness_view(current: dict[str, Any]) -> tuple[str, int, int, bool, int, bool]:
root_mismatch = bool(current.get("remotePrekeyRootMismatch"))
policy_fingerprint = ""
witness_count = 0
witness_threshold = 0
witness_domain_count = 0
if root_mismatch:
policy_fingerprint = str(
current.get("remotePrekeyObservedRootWitnessPolicyFingerprint", "") or ""
).strip().lower()
witness_count = int(current.get("remotePrekeyObservedRootWitnessCount", 0) or 0)
witness_threshold = int(current.get("remotePrekeyObservedRootWitnessThreshold", 0) or 0)
witness_domain_count = int(current.get("remotePrekeyObservedRootWitnessDomainCount", 0) or 0)
else:
policy_fingerprint = str(current.get("remotePrekeyRootWitnessPolicyFingerprint", "") or "").strip().lower()
witness_count = int(current.get("remotePrekeyRootWitnessCount", 0) or 0)
witness_threshold = int(current.get("remotePrekeyRootWitnessThreshold", 0) or 0)
witness_domain_count = int(current.get("remotePrekeyRootWitnessDomainCount", 0) or 0)
if witness_threshold <= 0:
policy_fingerprint = policy_fingerprint or str(
current.get("invitePinnedRootWitnessPolicyFingerprint", "") or ""
).strip().lower()
witness_count = max(witness_count, int(current.get("invitePinnedRootWitnessCount", 0) or 0))
witness_threshold = max(witness_threshold, int(current.get("invitePinnedRootWitnessThreshold", 0) or 0))
witness_domain_count = max(
witness_domain_count,
int(current.get("invitePinnedRootWitnessDomainCount", 0) or 0),
)
legacy_single_witness = witness_threshold <= 0
if legacy_single_witness:
witness_threshold = 1
if witness_count <= 0:
witness_count = 1
if witness_domain_count <= 0:
witness_domain_count = 1
elif witness_count > 0 and witness_domain_count <= 0:
witness_domain_count = 1
quorum_met = witness_threshold > 0 and witness_count >= witness_threshold
independent_quorum_met = witness_threshold > 0 and witness_domain_count >= witness_threshold
return (
policy_fingerprint,
max(0, witness_count),
max(0, witness_threshold),
quorum_met,
max(0, witness_domain_count),
independent_quorum_met,
)
def describe_contact_trust(contact: dict[str, Any] | None) -> dict[str, Any]:
current = dict(contact or {})
from services.mesh.mesh_rollout_flags import wormhole_root_witness_finality_enforce
from services.mesh.mesh_wormhole_root_manifest import root_witness_finality_met as root_witness_finality_met_view
level = str(current.get("trust_level", "") or "").strip()
if level not in TRUST_LEVELS:
level = "unpinned"
transparency_conflict = bool(current.get("remotePrekeyTransparencyConflict"))
registry_mismatch = bool(current.get("verify_mismatch"))
legacy_lookup = str(current.get("remotePrekeyLookupMode", "") or "").strip().lower() == "legacy_agent_id"
root_attested = bool(
str(current.get("invitePinnedRootFingerprint", "") or "").strip()
or str(current.get("remotePrekeyRootFingerprint", "") or "").strip()
)
root_witnessed = bool(
str(current.get("invitePinnedRootManifestFingerprint", "") or "").strip()
or str(current.get("remotePrekeyRootManifestFingerprint", "") or "").strip()
or str(current.get("remotePrekeyObservedRootManifestFingerprint", "") or "").strip()
)
root_mismatch = bool(current.get("remotePrekeyRootMismatch"))
root_manifest_generation, root_rotation_proven = _contact_root_rotation_view(current)
(
root_witness_policy_fingerprint,
root_witness_count,
root_witness_threshold,
root_witness_quorum_met,
root_witness_domain_count,
root_witness_independent_quorum_met,
) = _contact_root_witness_view(current) if root_witnessed else ("", 0, 0, False, 0, False)
root_rotation_unproven = bool(root_witnessed and root_manifest_generation > 1 and not root_rotation_proven)
invite_attested = bool(
str(current.get("invitePinnedTrustFingerprint", "") or "").strip()
or int(current.get("invitePinnedAt", 0) or 0) > 0
)
if not root_attested:
root_distribution_state = "none"
elif not root_witnessed:
root_distribution_state = "internal_only"
elif not root_witness_quorum_met:
root_distribution_state = "witness_policy_not_met"
elif root_witness_threshold <= 1:
root_distribution_state = "single_witness"
else:
root_distribution_state = "quorum_witnessed"
if not root_attested:
root_witness_provenance_state = "none"
elif not root_witnessed:
root_witness_provenance_state = "internal_only"
elif not root_witness_quorum_met:
root_witness_provenance_state = "witness_policy_not_met"
elif root_witness_threshold <= 1:
root_witness_provenance_state = "single_witness"
elif root_witness_independent_quorum_met:
root_witness_provenance_state = "independent_quorum"
else:
root_witness_provenance_state = "local_quorum"
root_witness_finality_met = root_witness_finality_met_view(
witness_threshold=root_witness_threshold,
witness_quorum_met=root_witness_quorum_met,
witness_independent_quorum_met=root_witness_independent_quorum_met,
)
enforce_root_witness_finality = bool(wormhole_root_witness_finality_enforce())
root_distribution_upgrade_needed = bool(
root_attested and root_distribution_state in ("internal_only", "single_witness", "witness_policy_not_met")
)
root_finality_upgrade_needed = bool(
root_attested
and root_distribution_state == "quorum_witnessed"
and root_witness_threshold > 1
and not root_witness_finality_met
)
witnessed_root_label = (
"independently quorum-witnessed stable root identity"
if root_witness_provenance_state == "independent_quorum"
else (
"locally quorum-witnessed stable root identity"
if root_witness_provenance_state == "local_quorum"
else (
"single-witness stable root identity"
if root_witness_provenance_state == "single_witness"
else "witnessed stable root identity"
)
)
)
label = "UNVERIFIED"
severity = "warn"
detail = "No trusted first-contact anchor. Import a signed invite before secure first contact."
recommended_action = TRUST_RECOMMENDED_ACTIONS.get(level, "show_sas")
if level == "tofu_pinned":
label = "TOFU PINNED"
detail = (
"First contact is pinned on first sight only. Verify SAS before sensitive use."
if not root_attested
else (
(
(
f"Current prekey is seen under one {witnessed_root_label}, but first contact is still TOFU-only. Verify SAS before sensitive use."
if root_witness_provenance_state in ("independent_quorum", "local_quorum")
else (
"Current prekey is seen under one single-witness stable root, but first contact is still TOFU-only. Re-import a current signed invite if you want stronger quorum witness provenance."
if root_witness_provenance_state == "single_witness"
else "Current prekey is seen under a witnessed stable root, but the current witness policy is not satisfied. Replace or re-import the signed invite before treating this root as strong first-contact provenance."
)
)
if not root_rotation_unproven
else "Current prekey is seen under one witnessed stable root, but that root rotation lacks previous-root proof. Replace the signed invite before treating this root as continuous."
)
if root_witnessed
else "Current prekey is seen under one stable root, but first contact is still TOFU-only. Verify SAS before sensitive use."
)
)
elif level == "invite_pinned":
label = "INVITE PINNED"
detail = (
"First contact is anchored to an imported signed invite. SAS is optional but recommended for continuity."
if not root_attested
else (
(
(
f"First contact is anchored to an imported signed invite and an {witnessed_root_label}. SAS is optional but recommended for continuity."
if root_witness_provenance_state in ("independent_quorum", "local_quorum")
else (
"First contact is anchored to an imported signed invite and a single-witness stable root identity. Re-import a current signed invite if you want stronger quorum witness provenance."
if root_witness_provenance_state == "single_witness"
else "First contact is anchored to an imported signed invite and a witnessed stable root identity, but the current witness policy is not satisfied. Replace the signed invite before private use."
)
)
if not root_rotation_unproven
else "First contact is anchored to an imported signed invite and a witnessed stable root identity, but its current root rotation lacks previous-root proof. Replace the signed invite before private use."
)
if root_witnessed
else "First contact is anchored to an imported signed invite and a stable root identity. Re-import a current signed invite to refresh witnessed root distribution."
)
)
if root_distribution_upgrade_needed or root_rotation_unproven:
recommended_action = "import_invite"
elif level == "sas_verified":
label = "SAS VERIFIED"
severity = "good"
detail = (
"This contact was confirmed with a shared SAS phrase on the current pinned fingerprint."
if not root_attested
else (
(
(
f"This contact was SAS confirmed on the current pinned fingerprint and an {witnessed_root_label}."
if root_witness_provenance_state in ("independent_quorum", "local_quorum")
else (
"This contact was SAS confirmed on the current pinned fingerprint and single-witness stable root identity. Re-import a current signed invite if you want stronger quorum witness provenance."
if root_witness_provenance_state == "single_witness"
else "This contact was SAS confirmed on the current pinned fingerprint, but the current witnessed root does not satisfy its witness policy."
)
)
if not root_rotation_unproven
else "This contact was SAS confirmed on the current pinned fingerprint, but its current witnessed root rotation lacks previous-root proof."
)
if root_witnessed
else "This contact was SAS confirmed on the current pinned fingerprint and stable root identity, but its root distribution is still internal-only."
)
)
if root_distribution_upgrade_needed or root_rotation_unproven:
recommended_action = "import_invite"
elif level == "mismatch":
label = "REVERIFY"
severity = "danger"
detail = (
"Observed prekey identity changed. Compare SAS before trusting the new key."
if not root_mismatch
else (
(
f"Observed {witnessed_root_label} changed. Replace the invite or compare SAS before trusting the new key."
if root_witness_provenance_state in ("independent_quorum", "local_quorum")
else (
"Observed single-witness stable root identity changed. Replace the invite or compare SAS before trusting the new key."
if root_witness_provenance_state == "single_witness"
else "Observed stable root identity changed and its current witness policy is not satisfied. Replace the invite before trusting the new key."
)
)
if not root_rotation_unproven
else "Observed witnessed stable root rotation lacks previous-root proof. Replace the invite before trusting this root change."
)
)
elif level == "continuity_broken":
label = "CONTINUITY BROKEN"
severity = "danger"
detail = (
"Pinned trust anchor changed. Re-verify SAS or replace the invite before private use."
if not root_mismatch
else (
(
f"Pinned {witnessed_root_label} changed. Replace the signed invite or re-verify SAS before private use."
if root_witness_provenance_state in ("independent_quorum", "local_quorum")
else (
"Pinned single-witness stable root identity changed. Replace the signed invite or re-verify SAS before private use."
if root_witness_provenance_state == "single_witness"
else "Pinned stable root identity changed and its current witness policy is not satisfied. Replace the signed invite or re-verify SAS before private use."
)
)
if not root_rotation_unproven
else "Pinned witnessed stable root changed without previous-root proof. Replace the signed invite or re-verify SAS before private use."
)
)
if transparency_conflict:
detail = (
"Prekey transparency history conflicted. Trust stays degraded until you explicitly acknowledge the changed fingerprint."
)
elif root_rotation_unproven and level not in ("mismatch", "continuity_broken"):
recommended_action = "import_invite"
elif root_distribution_state == "witness_policy_not_met" and level not in ("mismatch", "continuity_broken"):
recommended_action = "import_invite"
elif enforce_root_witness_finality and root_finality_upgrade_needed and level not in ("mismatch", "continuity_broken"):
recommended_action = "import_invite"
elif legacy_lookup and level not in ("mismatch", "continuity_broken"):
detail = (
f"{detail} This contact still bootstraps through legacy direct agent ID lookup. "
"Import or re-import a signed invite to avoid stable-ID lookup before removal."
)
recommended_action = "import_invite"
return {
"state": level,
"label": label,
"severity": severity,
"detail": detail,
"verifiedFirstContact": (
level in VERIFIED_FIRST_CONTACT_TRUST_LEVELS
and not root_rotation_unproven
and root_distribution_state != "witness_policy_not_met"
and not (enforce_root_witness_finality and root_finality_upgrade_needed)
),
"recommendedAction": recommended_action,
"legacyLookup": legacy_lookup,
"inviteAttested": invite_attested,
"rootAttested": root_attested,
"rootWitnessed": root_witnessed,
"rootDistributionState": root_distribution_state,
"rootWitnessPolicyFingerprint": root_witness_policy_fingerprint,
"rootWitnessCount": root_witness_count,
"rootWitnessThreshold": root_witness_threshold,
"rootWitnessQuorumMet": root_witness_quorum_met,
"rootWitnessProvenanceState": root_witness_provenance_state,
"rootWitnessDomainCount": root_witness_domain_count,
"rootWitnessIndependentQuorumMet": root_witness_independent_quorum_met,
"rootWitnessFinalityMet": root_witness_finality_met,
"rootManifestGeneration": root_manifest_generation,
"rootRotationProven": root_rotation_proven,
"rootMismatch": root_mismatch,
"registryMismatch": registry_mismatch,
"transparencyConflict": transparency_conflict,
}
def describe_contact_alias_state(contact: dict[str, Any] | None) -> dict[str, Any]:
current = dict(contact or {})
trust_summary = dict(current.get("trustSummary") or {})
now_ms = int(time.time() * 1000)
active_alias = str(current.get("sharedAlias", "") or "").strip()
pending_alias = str(current.get("pendingSharedAlias", "") or "").strip()
grace_until = int(current.get("sharedAliasGraceUntil", 0) or 0)
rotated_at = int(current.get("sharedAliasRotatedAt", 0) or 0)
has_peer_dh = bool(
str(
current.get("dhPubKey")
or current.get("invitePinnedDhPubKey")
or ""
).strip()
)
verified_first_contact = bool(trust_summary.get("verifiedFirstContact"))
pending_active = bool(pending_alias)
grace_remaining_ms = max(0, grace_until - now_ms) if pending_alias and grace_until > 0 else 0
can_prepare_issue = bool(not active_alias and has_peer_dh and not pending_active)
can_prepare_rotation = bool(active_alias and has_peer_dh and not pending_active)
background_prepare_allowed = bool(
verified_first_contact and (can_prepare_issue or can_prepare_rotation)
)
if pending_active:
state = "pending_promotion"
recommended_action = "wait_for_promotion"
elif not has_peer_dh:
state = "needs_peer_dh"
recommended_action = "refresh_contact"
elif not active_alias:
state = "ready_to_issue"
recommended_action = (
"issue_alias"
if verified_first_contact
else str(trust_summary.get("recommendedAction", "") or "verify_contact")
)
else:
state = "active"
recommended_action = (
"rotate_when_needed"
if verified_first_contact
else str(trust_summary.get("recommendedAction", "") or "verify_contact")
)
return {
"state": state,
"hasActiveAlias": bool(active_alias),
"hasPendingAlias": bool(pending_alias),
"graceUntil": grace_until,
"graceRemainingMs": grace_remaining_ms,
"lastRotatedAt": rotated_at,
"hasPeerDh": has_peer_dh,
"verifiedFirstContact": verified_first_contact,
"canPrepareIssue": can_prepare_issue,
"canPrepareRotation": can_prepare_rotation,
"backgroundPrepareAllowed": background_prepare_allowed,
"recommendedAction": recommended_action,
}
def accepted_contact_shared_aliases(
contact: dict[str, Any] | None,
*,
now_ms: int | None = None,
) -> list[str]:
current = _normalize_contact(contact)
accepted: list[str] = []
active_alias = str(current.get("sharedAlias", "") or "").strip()
pending_alias = str(current.get("pendingSharedAlias", "") or "").strip()
grace_until = int(current.get("sharedAliasGraceUntil", 0) or 0)
previous_alias = str(current.get("acceptedPreviousAlias", "") or "").strip()
previous_grace_until = int(current.get("acceptedPreviousGraceUntil", 0) or 0)
previous_hard_grace_until = int(current.get("acceptedPreviousHardGraceUntil", 0) or 0)
previous_awaiting_reply = bool(current.get("acceptedPreviousAwaitingReply"))
if active_alias:
accepted.append(active_alias)
current_ms = int(now_ms) if now_ms is not None else int(time.time() * 1000)
if pending_alias and grace_until > current_ms and pending_alias not in accepted:
accepted.append(pending_alias)
if previous_alias and previous_alias not in accepted:
within_default_grace = previous_grace_until > current_ms
within_hard_cap = previous_awaiting_reply and previous_hard_grace_until > current_ms
if within_default_grace or within_hard_cap:
accepted.append(previous_alias)
return accepted
def contact_shared_alias_accepted(
contact: dict[str, Any] | None,
alias: str,
*,
now_ms: int | None = None,
) -> bool:
alias_key = str(alias or "").strip()
if not alias_key:
return False
return alias_key in accepted_contact_shared_aliases(contact, now_ms=now_ms)
def _normalize_contact(value: dict[str, Any] | None) -> dict[str, Any]:
defaults = _default_contact()
merged = dict(defaults)
if isinstance(value, dict):
merged.update(value)
current = {key: merged.get(key, defaults[key]) for key in defaults.keys()}
current["alias"] = str(current.get("alias", "") or "")
current["blocked"] = bool(current.get("blocked"))
current["dhPubKey"] = str(current.get("dhPubKey", "") or "")
current["dhAlgo"] = str(current.get("dhAlgo", "") or "")
current["sharedAlias"] = str(current.get("sharedAlias", "") or "")
current["sharedAliasCounter"] = int(current.get("sharedAliasCounter", 0) or 0)
current["sharedAliasPublicKey"] = str(current.get("sharedAliasPublicKey", "") or "")
current["sharedAliasPublicKeyAlgo"] = str(current.get("sharedAliasPublicKeyAlgo", "Ed25519") or "Ed25519")
raw_dm_identity_id = str(
current.get("dmIdentityId", "")
or merged.get("dm_identity_id", "")
or ""
).strip()
if raw_dm_identity_id:
try:
from services.mesh.mesh_wormhole_dead_drop import dead_drop_redact_label
current["dmIdentityId"] = dead_drop_redact_label(raw_dm_identity_id)
except Exception:
current["dmIdentityId"] = raw_dm_identity_id
else:
current["dmIdentityId"] = ""
current["previousSharedAliases"] = [
str(item or "") for item in list(current.get("previousSharedAliases") or []) if str(item or "").strip()
][-2:]
current["pendingSharedAlias"] = str(current.get("pendingSharedAlias", "") or "")
current["pendingSharedAliasCounter"] = int(current.get("pendingSharedAliasCounter", 0) or 0)
current["pendingSharedAliasPublicKey"] = str(current.get("pendingSharedAliasPublicKey", "") or "")
current["pendingSharedAliasPublicKeyAlgo"] = str(
current.get("pendingSharedAliasPublicKeyAlgo", "Ed25519") or "Ed25519"
)
current["pendingSharedAliasGraceMs"] = int(current.get("pendingSharedAliasGraceMs", 0) or 0)
current["acceptedPreviousAlias"] = str(current.get("acceptedPreviousAlias", "") or "")
current["acceptedPreviousAliasCounter"] = int(current.get("acceptedPreviousAliasCounter", 0) or 0)
current["acceptedPreviousAliasPublicKey"] = str(current.get("acceptedPreviousAliasPublicKey", "") or "")
current["acceptedPreviousAliasPublicKeyAlgo"] = str(
current.get("acceptedPreviousAliasPublicKeyAlgo", "Ed25519") or "Ed25519"
)
current["aliasBindingSeq"] = int(current.get("aliasBindingSeq", 0) or 0)
current["aliasBindingPendingReason"] = str(current.get("aliasBindingPendingReason", "") or "")
current["invitePinnedTrustFingerprint"] = str(current.get("invitePinnedTrustFingerprint", "") or "").strip().lower()
current["invitePinnedNodeId"] = str(current.get("invitePinnedNodeId", "") or "")
current["invitePinnedPublicKey"] = str(current.get("invitePinnedPublicKey", "") or "")
current["invitePinnedPublicKeyAlgo"] = str(current.get("invitePinnedPublicKeyAlgo", "") or "")
current["invitePinnedDhPubKey"] = str(current.get("invitePinnedDhPubKey", "") or "")
current["invitePinnedDhAlgo"] = str(current.get("invitePinnedDhAlgo", "") or "")
current["invitePinnedPrekeyLookupHandle"] = str(current.get("invitePinnedPrekeyLookupHandle", "") or "")
current["invitePinnedRootFingerprint"] = str(current.get("invitePinnedRootFingerprint", "") or "").strip().lower()
current["invitePinnedRootManifestFingerprint"] = str(
current.get("invitePinnedRootManifestFingerprint", "") or ""
).strip().lower()
current["invitePinnedRootWitnessPolicyFingerprint"] = str(
current.get("invitePinnedRootWitnessPolicyFingerprint", "") or ""
).strip().lower()
current["invitePinnedRootNodeId"] = str(current.get("invitePinnedRootNodeId", "") or "")
current["invitePinnedRootPublicKey"] = str(current.get("invitePinnedRootPublicKey", "") or "")
current["invitePinnedRootPublicKeyAlgo"] = str(current.get("invitePinnedRootPublicKeyAlgo", "") or "")
current["remotePrekeyFingerprint"] = str(current.get("remotePrekeyFingerprint", "") or "")
current["remotePrekeyObservedFingerprint"] = str(current.get("remotePrekeyObservedFingerprint", "") or "")
current["remotePrekeyRootFingerprint"] = str(current.get("remotePrekeyRootFingerprint", "") or "").strip().lower()
current["remotePrekeyRootManifestFingerprint"] = str(
current.get("remotePrekeyRootManifestFingerprint", "") or ""
).strip().lower()
current["remotePrekeyRootWitnessPolicyFingerprint"] = str(
current.get("remotePrekeyRootWitnessPolicyFingerprint", "") or ""
).strip().lower()
current["remotePrekeyObservedRootFingerprint"] = str(
current.get("remotePrekeyObservedRootFingerprint", "") or ""
).strip().lower()
current["remotePrekeyObservedRootManifestFingerprint"] = str(
current.get("remotePrekeyObservedRootManifestFingerprint", "") or ""
).strip().lower()
current["remotePrekeyObservedRootWitnessPolicyFingerprint"] = str(
current.get("remotePrekeyObservedRootWitnessPolicyFingerprint", "") or ""
).strip().lower()
current["remotePrekeyRootNodeId"] = str(current.get("remotePrekeyRootNodeId", "") or "")
current["remotePrekeyRootPublicKey"] = str(current.get("remotePrekeyRootPublicKey", "") or "")
current["remotePrekeyRootPublicKeyAlgo"] = str(current.get("remotePrekeyRootPublicKeyAlgo", "") or "")
current["remotePrekeyTransparencyHead"] = str(
current.get("remotePrekeyTransparencyHead", "") or ""
).strip().lower()
current["remotePrekeyLookupMode"] = str(current.get("remotePrekeyLookupMode", "") or "").strip().lower()
tl = str(current.get("trust_level", "") or "").strip()
current["trust_level"] = tl if tl in TRUST_LEVELS else "unpinned"
for key in (
"sharedAliasGraceUntil",
"sharedAliasRotatedAt",
"acceptedPreviousGraceUntil",
"acceptedPreviousHardGraceUntil",
"aliasBindingPreparedAt",
"aliasGateJoinAppliedSeq",
"verified_at",
"invitePinnedIssuedAt",
"invitePinnedExpiresAt",
"invitePinnedAt",
"invitePinnedRootManifestGeneration",
"invitePinnedRootWitnessThreshold",
"invitePinnedRootWitnessCount",
"invitePinnedRootWitnessDomainCount",
"remotePrekeyRootPinnedAt",
"remotePrekeyRootLastSeenAt",
"remotePrekeyRootWitnessThreshold",
"remotePrekeyRootWitnessCount",
"remotePrekeyRootWitnessDomainCount",
"remotePrekeyRootManifestGeneration",
"remotePrekeyObservedRootWitnessThreshold",
"remotePrekeyObservedRootWitnessCount",
"remotePrekeyObservedRootWitnessDomainCount",
"remotePrekeyObservedRootManifestGeneration",
"remotePrekeyPinnedAt",
"remotePrekeyLastSeenAt",
"remotePrekeySequence",
"remotePrekeySignedAt",
"remotePrekeyTransparencySize",
"remotePrekeyTransparencySeenAt",
"witness_count",
"witness_checked_at",
"vouch_count",
"vouch_checked_at",
"updated_at",
):
current[key] = int(current.get(key, 0) or 0)
for key in (
"verify_inband",
"verify_registry",
"verified",
"verify_mismatch",
"acceptedPreviousAwaitingReply",
"invitePinnedRootRotationProven",
"remotePrekeyRootMismatch",
"remotePrekeyRootRotationProven",
"remotePrekeyObservedRootRotationProven",
"remotePrekeyMismatch",
"remotePrekeyTransparencyConflict",
):
current[key] = bool(current.get(key))
current["trustSummary"] = describe_contact_trust(current)
current["aliasSummary"] = describe_contact_alias_state(current)
return current
def get_contact_trust_level(peer_id: str) -> str:
peer_key = str(peer_id or "").strip()
if not peer_key:
return "unpinned"
contacts = _read_contacts()
current = _normalize_contact(contacts.get(peer_key))
return str(current.get("trust_level", "") or "").strip() or "unpinned"
def verified_first_contact_requirement(peer_id: str = "", trust_level: str | None = None) -> dict[str, Any]:
peer_key = str(peer_id or "").strip()
if peer_key:
contacts = _read_contacts()
current = _normalize_contact(contacts.get(peer_key))
trust_summary = dict(current.get("trustSummary") or {})
state = str(trust_summary.get("state", current.get("trust_level", "")) or "").strip() or "unpinned"
if bool(trust_summary.get("verifiedFirstContact")):
return {
"ok": True,
"trust_level": state,
}
if state in ("mismatch", "continuity_broken"):
return {
"ok": False,
"trust_level": state,
"detail": "remote prekey identity changed; verification required",
}
if bool(trust_summary.get("rootWitnessed")) and int(trust_summary.get("rootManifestGeneration", 0) or 0) > 1 and not bool(
trust_summary.get("rootRotationProven")
):
return {
"ok": False,
"trust_level": state,
"detail": str(
trust_summary.get("detail", "")
or "current witnessed root rotation lacks previous-root proof",
),
}
if (
state in VERIFIED_FIRST_CONTACT_TRUST_LEVELS
and
str(trust_summary.get("rootDistributionState", "") or "") == "quorum_witnessed"
and int(trust_summary.get("rootWitnessThreshold", 0) or 0) > 1
and not bool(trust_summary.get("rootWitnessFinalityMet"))
):
return {
"ok": False,
"trust_level": state,
"detail": "independent quorum root witness finality required before secure first contact",
}
return {
"ok": False,
"trust_level": state,
"detail": "signed invite or SAS verification required before secure first contact",
}
level = str(trust_level or "").strip() or get_contact_trust_level(peer_id)
if level in VERIFIED_FIRST_CONTACT_TRUST_LEVELS:
return {
"ok": True,
"trust_level": level,
}
if level in ("mismatch", "continuity_broken"):
return {
"ok": False,
"trust_level": level,
"detail": "remote prekey identity changed; verification required",
}
return {
"ok": False,
"trust_level": level or "unpinned",
"detail": "signed invite or SAS verification required before secure first contact",
}
def _merge_alias_history(*aliases: str, limit: int = 2) -> list[str]:
unique: set[str] = set()
ordered: list[str] = []
for alias in aliases:
value = str(alias or "").strip()
if not value or value in unique:
continue
unique.add(value)
ordered.append(value)
if len(ordered) >= limit:
break
return ordered
def _promote_pending_alias_if_due(contact: dict[str, Any]) -> tuple[dict[str, Any], bool]:
return _normalize_contact(contact), False
def _read_contacts() -> dict[str, dict[str, Any]]:
try:
raw = read_secure_json(CONTACTS_FILE, lambda: {})
except Exception:
import logging
logging.getLogger(__name__).warning(
"Contacts file could not be decrypted — starting with empty contacts"
)
CONTACTS_FILE.unlink(missing_ok=True)
return {}
if not isinstance(raw, dict):
return {}
contacts: dict[str, dict[str, Any]] = {}
changed = False
for peer_id, value in raw.items():
key = str(peer_id or "").strip()
if not key:
continue
normalized, promoted = _promote_pending_alias_if_due(value if isinstance(value, dict) else {})
invite_lookup_upgraded = _promote_invite_lookup_mode(normalized)
contacts[key] = normalized
changed = changed or promoted or invite_lookup_upgraded
if changed:
_write_contacts(contacts)
return contacts
def _write_contacts(contacts: dict[str, dict[str, Any]]) -> None:
DATA_DIR.mkdir(parents=True, exist_ok=True)
payload: dict[str, dict[str, Any]] = {}
for peer_id, contact in contacts.items():
key = str(peer_id or "").strip()
if not key:
continue
normalized = _normalize_contact(contact)
normalized.pop("trustSummary", None)
normalized.pop("aliasSummary", None)
payload[key] = normalized
write_secure_json(CONTACTS_FILE, payload)
def _normalize_sas_phrase(value: str) -> str:
return " ".join(str(value or "").strip().lower().split())
def _derive_expected_contact_sas_phrase(
peer_id: str,
*,
peer_ref: str = "",
words: int = 8,
peer_dh_pub_override: str = "",
) -> dict[str, Any]:
peer_key = str(peer_id or "").strip()
if not peer_key:
raise ValueError("peer_id required")
contacts = _read_contacts()
current = _normalize_contact(contacts.get(peer_key))
peer_dh_pub = str(
peer_dh_pub_override
or current.get("dhPubKey")
or current.get("invitePinnedDhPubKey")
or ""
).strip()
if not peer_dh_pub:
return {
"ok": False,
"detail": "peer dh identity unavailable for sas verification",
}
from services.mesh.mesh_wormhole_dead_drop import derive_sas_phrase
return derive_sas_phrase(
peer_id=peer_key,
peer_dh_pub=peer_dh_pub,
words=words,
peer_ref=str(peer_ref or ""),
)
def list_wormhole_dm_contacts() -> dict[str, dict[str, Any]]:
return _read_contacts()
def _promote_invite_lookup_mode(contact: dict[str, Any], *, now: int | None = None) -> bool:
current = dict(contact or {})
lookup_handle = str(current.get("invitePinnedPrekeyLookupHandle", "") or "").strip()
if not lookup_handle:
return False
if str(current.get("remotePrekeyLookupMode", "") or "").strip().lower() == "invite_lookup_handle":
return False
current["remotePrekeyLookupMode"] = "invite_lookup_handle"
current["updated_at"] = int(now if now is not None else time.time())
contact.clear()
contact.update(_normalize_contact(current))
return True
def upgrade_invite_scoped_contact_preferences() -> int:
contacts = _read_contacts()
now = int(time.time())
changed = 0
for peer_id, raw_contact in list(contacts.items()):
current = _normalize_contact(raw_contact)
if _promote_invite_lookup_mode(current, now=now):
contacts[peer_id] = current
changed += 1
if changed:
_write_contacts(contacts)
return changed
def preferred_prekey_lookup_handle(peer_id: str) -> str:
peer_key = str(peer_id or "").strip()
if not peer_key:
return ""
contacts = _read_contacts()
current = _normalize_contact(contacts.get(peer_key))
if _promote_invite_lookup_mode(current):
contacts[peer_key] = current
_write_contacts(contacts)
return str(current.get("invitePinnedPrekeyLookupHandle", "") or "").strip()
def compatibility_lookup_readiness_snapshot() -> dict[str, Any]:
contacts = _read_contacts()
stored_legacy_lookup_contacts = 0
stored_invite_lookup_contacts = 0
for raw_contact in list(contacts.values()):
current = _normalize_contact(raw_contact)
lookup_mode = str(current.get("remotePrekeyLookupMode", "") or "").strip().lower()
lookup_handle = str(current.get("invitePinnedPrekeyLookupHandle", "") or "").strip()
if lookup_handle:
stored_invite_lookup_contacts += 1
if lookup_mode == "legacy_agent_id":
stored_legacy_lookup_contacts += 1
return {
"stored_legacy_lookup_contacts_present": stored_legacy_lookup_contacts > 0,
"stored_legacy_lookup_contacts": stored_legacy_lookup_contacts,
"stored_invite_lookup_contacts": stored_invite_lookup_contacts,
}
def upsert_wormhole_dm_contact(peer_id: str, updates: dict[str, Any]) -> dict[str, Any]:
return _upsert_wormhole_dm_contact(peer_id, updates, sanitize_updates=True)
def upsert_wormhole_dm_contact_internal(peer_id: str, updates: dict[str, Any]) -> dict[str, Any]:
return _upsert_wormhole_dm_contact(peer_id, updates, sanitize_updates=False)
def _upsert_wormhole_dm_contact(
peer_id: str,
updates: dict[str, Any],
*,
sanitize_updates: bool,
) -> dict[str, Any]:
peer_id = str(peer_id or "").strip()
if not peer_id:
raise ValueError("peer_id required")
contacts = _read_contacts()
current = _normalize_contact(contacts.get(peer_id))
safe_updates = _sanitize_client_contact_updates(updates) if sanitize_updates else dict(updates or {})
merged = _normalize_contact({**current, **safe_updates})
merged["updated_at"] = int(time.time())
contacts[peer_id] = merged
_write_contacts(contacts)
return merged
def roll_forward_invite_lookup_handles(
mapping: dict[str, str] | None,
*,
invite_node_id: str = "",
) -> int:
current_mapping = {
str(old or "").strip(): str(new or "").strip()
for old, new in dict(mapping or {}).items()
if str(old or "").strip() and str(new or "").strip() and str(old or "").strip() != str(new or "").strip()
}
if not current_mapping:
return 0
expected_node_id = str(invite_node_id or "").strip()
contacts = _read_contacts()
now = int(time.time())
changed = 0
for peer_id, raw_contact in list(contacts.items()):
current = _normalize_contact(raw_contact)
if expected_node_id and str(current.get("invitePinnedNodeId", "") or "").strip() != expected_node_id:
continue
old_handle = str(current.get("invitePinnedPrekeyLookupHandle", "") or "").strip()
new_handle = current_mapping.get(old_handle, "")
if not new_handle:
continue
current["invitePinnedPrekeyLookupHandle"] = new_handle
current["updated_at"] = now
contacts[peer_id] = _normalize_contact(current)
changed += 1
if changed:
_write_contacts(contacts)
return changed
def pin_wormhole_dm_invite(
peer_id: str,
*,
invite_payload: dict[str, Any],
alias: str = "",
attested: bool = True,
) -> dict[str, Any]:
peer_key = str(peer_id or "").strip()
if not peer_key:
raise ValueError("peer_id required")
payload = dict(invite_payload or {})
trust_fingerprint = str(payload.get("trust_fingerprint", "") or "").strip().lower()
if not trust_fingerprint:
raise ValueError("invite trust_fingerprint required")
contacts = _read_contacts()
current = _normalize_contact(contacts.get(peer_key))
now = int(time.time())
trust_level = "invite_pinned" if bool(attested) else "tofu_pinned"
identity_dh_pub_key = str(payload.get("identity_dh_pub_key", "") or "")
dh_algo = str(payload.get("dh_algo", "X25519") or "X25519")
prekey_lookup_handle = str(payload.get("prekey_lookup_handle", "") or "")
if str(alias or "").strip():
current["alias"] = str(alias or "").strip()
current["dhPubKey"] = identity_dh_pub_key
current["dhAlgo"] = dh_algo
current["invitePinnedPrekeyLookupHandle"] = prekey_lookup_handle
current["invitePinnedRootFingerprint"] = str(payload.get("root_fingerprint", "") or "").strip().lower()
current["invitePinnedRootManifestFingerprint"] = str(
payload.get("root_manifest_fingerprint", "") or ""
).strip().lower()
current["invitePinnedRootWitnessPolicyFingerprint"] = str(
payload.get("root_witness_policy_fingerprint", "") or ""
).strip().lower()
current["invitePinnedRootWitnessThreshold"] = int(payload.get("root_witness_threshold", 0) or 0)
current["invitePinnedRootWitnessCount"] = int(payload.get("root_witness_count", 0) or 0)
current["invitePinnedRootWitnessDomainCount"] = int(payload.get("root_witness_domain_count", 0) or 0)
current["invitePinnedRootManifestGeneration"] = int(payload.get("root_manifest_generation", 0) or 0)
current["invitePinnedRootRotationProven"] = bool(
int(payload.get("root_manifest_generation", 0) or 0) <= 1 or payload.get("root_rotation_proven")
)
current["invitePinnedRootNodeId"] = str(payload.get("root_node_id", "") or "")
current["invitePinnedRootPublicKey"] = str(payload.get("root_public_key", "") or "")
current["invitePinnedRootPublicKeyAlgo"] = str(payload.get("root_public_key_algo", "Ed25519") or "Ed25519")
current["invitePinnedIssuedAt"] = int(payload.get("issued_at", 0) or 0)
current["invitePinnedExpiresAt"] = int(payload.get("expires_at", 0) or 0)
current["remotePrekeyLookupMode"] = "invite_lookup_handle" if prekey_lookup_handle else ""
current["remotePrekeyFingerprint"] = trust_fingerprint
current["remotePrekeyObservedFingerprint"] = trust_fingerprint
current["remotePrekeyRootFingerprint"] = str(payload.get("root_fingerprint", "") or "").strip().lower()
current["remotePrekeyObservedRootFingerprint"] = str(payload.get("root_fingerprint", "") or "").strip().lower()
current["remotePrekeyRootManifestFingerprint"] = str(
payload.get("root_manifest_fingerprint", "") or ""
).strip().lower()
current["remotePrekeyRootWitnessPolicyFingerprint"] = str(
payload.get("root_witness_policy_fingerprint", "") or ""
).strip().lower()
current["remotePrekeyRootWitnessThreshold"] = int(payload.get("root_witness_threshold", 0) or 0)
current["remotePrekeyRootWitnessCount"] = int(payload.get("root_witness_count", 0) or 0)
current["remotePrekeyRootWitnessDomainCount"] = int(payload.get("root_witness_domain_count", 0) or 0)
current["remotePrekeyObservedRootManifestFingerprint"] = str(
payload.get("root_manifest_fingerprint", "") or ""
).strip().lower()
current["remotePrekeyObservedRootWitnessPolicyFingerprint"] = str(
payload.get("root_witness_policy_fingerprint", "") or ""
).strip().lower()
current["remotePrekeyObservedRootWitnessThreshold"] = int(payload.get("root_witness_threshold", 0) or 0)
current["remotePrekeyObservedRootWitnessCount"] = int(payload.get("root_witness_count", 0) or 0)
current["remotePrekeyObservedRootWitnessDomainCount"] = int(payload.get("root_witness_domain_count", 0) or 0)
current["remotePrekeyRootManifestGeneration"] = int(payload.get("root_manifest_generation", 0) or 0)
current["remotePrekeyObservedRootManifestGeneration"] = int(payload.get("root_manifest_generation", 0) or 0)
current["remotePrekeyRootRotationProven"] = bool(
int(payload.get("root_manifest_generation", 0) or 0) <= 1 or payload.get("root_rotation_proven")
)
current["remotePrekeyObservedRootRotationProven"] = bool(
int(payload.get("root_manifest_generation", 0) or 0) <= 1 or payload.get("root_rotation_proven")
)
current["remotePrekeyRootNodeId"] = str(payload.get("root_node_id", "") or "")
current["remotePrekeyRootPublicKey"] = str(payload.get("root_public_key", "") or "")
current["remotePrekeyRootPublicKeyAlgo"] = str(payload.get("root_public_key_algo", "Ed25519") or "Ed25519")
current["remotePrekeyRootPinnedAt"] = now
current["remotePrekeyRootLastSeenAt"] = now
current["remotePrekeyRootMismatch"] = False
current["remotePrekeyPinnedAt"] = now
current["remotePrekeyLastSeenAt"] = now
current["remotePrekeyMismatch"] = False
current["trust_level"] = trust_level
if attested:
current["invitePinnedTrustFingerprint"] = trust_fingerprint
current["invitePinnedNodeId"] = peer_key
current["invitePinnedPublicKey"] = str(payload.get("public_key", "") or "")
current["invitePinnedPublicKeyAlgo"] = str(payload.get("public_key_algo", "Ed25519") or "Ed25519")
current["invitePinnedDhPubKey"] = identity_dh_pub_key
current["invitePinnedDhAlgo"] = dh_algo
current["invitePinnedAt"] = now
else:
current["invitePinnedTrustFingerprint"] = ""
current["invitePinnedNodeId"] = ""
current["invitePinnedPublicKey"] = ""
current["invitePinnedPublicKeyAlgo"] = ""
current["invitePinnedDhPubKey"] = ""
current["invitePinnedDhAlgo"] = ""
current["invitePinnedRootFingerprint"] = ""
current["invitePinnedRootManifestFingerprint"] = ""
current["invitePinnedRootWitnessPolicyFingerprint"] = ""
current["invitePinnedRootWitnessThreshold"] = 0
current["invitePinnedRootWitnessCount"] = 0
current["invitePinnedRootWitnessDomainCount"] = 0
current["invitePinnedRootManifestGeneration"] = 0
current["invitePinnedRootRotationProven"] = False
current["invitePinnedRootNodeId"] = ""
current["invitePinnedRootPublicKey"] = ""
current["invitePinnedRootPublicKeyAlgo"] = ""
current["invitePinnedAt"] = 0
current["verified"] = False
current["verify_inband"] = False
current["verify_registry"] = False
current["verify_mismatch"] = False
current["verified_at"] = 0
current["updated_at"] = now
contacts[peer_key] = _normalize_contact(current)
_write_contacts(contacts)
return contacts[peer_key]
def delete_wormhole_dm_contact(peer_id: str) -> bool:
peer_id = str(peer_id or "").strip()
if not peer_id:
return False
contacts = _read_contacts()
if peer_id not in contacts:
return False
del contacts[peer_id]
_write_contacts(contacts)
return True
def observe_remote_prekey_identity(
peer_id: str,
*,
fingerprint: str,
sequence: int = 0,
signed_at: int = 0,
transparency_head: str = "",
transparency_size: int = 0,
witness_count: int | None = None,
witness_latest_at: int = 0,
root_fingerprint: str = "",
root_manifest_fingerprint: str = "",
root_witness_policy_fingerprint: str = "",
root_witness_threshold: int = 0,
root_witness_count: int = 0,
root_witness_domain_count: int = 0,
root_manifest_generation: int = 0,
root_rotation_proven: bool = False,
root_node_id: str = "",
root_public_key: str = "",
root_public_key_algo: str = "Ed25519",
) -> dict[str, Any]:
peer_key = str(peer_id or "").strip()
candidate = str(fingerprint or "").strip().lower()
if not peer_key:
raise ValueError("peer_id required")
if not candidate:
raise ValueError("fingerprint required")
contacts = _read_contacts()
current = _normalize_contact(contacts.get(peer_key))
now = int(time.time())
pinned = str(current.get("remotePrekeyFingerprint", "") or "").strip().lower()
invite_pinned = str(current.get("invitePinnedTrustFingerprint", "") or "").strip().lower()
pinned_root = str(current.get("remotePrekeyRootFingerprint", "") or "").strip().lower()
pinned_root_manifest = str(current.get("remotePrekeyRootManifestFingerprint", "") or "").strip().lower()
invite_pinned_root = str(current.get("invitePinnedRootFingerprint", "") or "").strip().lower()
invite_pinned_root_manifest = str(current.get("invitePinnedRootManifestFingerprint", "") or "").strip().lower()
observed_root = str(root_fingerprint or "").strip().lower()
observed_root_manifest = str(root_manifest_fingerprint or "").strip().lower()
observed_root_witness_policy = str(root_witness_policy_fingerprint or "").strip().lower()
observed_root_witness_threshold = int(root_witness_threshold or 0)
observed_root_witness_count = int(root_witness_count or 0)
observed_root_witness_domain_count = int(root_witness_domain_count or 0)
observed_root_manifest_generation = int(root_manifest_generation or 0)
observed_root_rotation_proven = bool(observed_root_manifest_generation <= 1 or root_rotation_proven)
prior_root_mismatch = bool(current.get("remotePrekeyRootMismatch"))
prior_sequence = int(current.get("remotePrekeySequence", 0) or 0)
prior_transparency_head = str(current.get("remotePrekeyTransparencyHead", "") or "").strip().lower()
prior_transparency_size = int(current.get("remotePrekeyTransparencySize", 0) or 0)
prior_transparency_conflict = bool(current.get("remotePrekeyTransparencyConflict"))
observed_transparency_head = str(transparency_head or "").strip().lower()
observed_transparency_size = int(transparency_size or 0)
observed_sequence = int(sequence or 0)
observed_signed_at = int(signed_at or 0)
transparency_conflict = False
if observed_transparency_head:
if prior_sequence > 0 and int(sequence or 0) > 0 and int(sequence or 0) < prior_sequence:
transparency_conflict = True
elif (
prior_sequence > 0
and int(sequence or 0) > 0
and int(sequence or 0) == prior_sequence
and prior_transparency_head
and observed_transparency_head != prior_transparency_head
):
transparency_conflict = True
elif prior_transparency_size > 0 and observed_transparency_size > 0 and observed_transparency_size < prior_transparency_size:
transparency_conflict = True
current["remotePrekeyObservedFingerprint"] = candidate
current["remotePrekeyLastSeenAt"] = now
if observed_root:
current["remotePrekeyObservedRootFingerprint"] = observed_root
current["remotePrekeyObservedRootManifestFingerprint"] = observed_root_manifest
current["remotePrekeyObservedRootWitnessPolicyFingerprint"] = observed_root_witness_policy
current["remotePrekeyObservedRootWitnessThreshold"] = observed_root_witness_threshold
current["remotePrekeyObservedRootWitnessCount"] = observed_root_witness_count
current["remotePrekeyObservedRootWitnessDomainCount"] = observed_root_witness_domain_count
current["remotePrekeyObservedRootManifestGeneration"] = observed_root_manifest_generation
current["remotePrekeyObservedRootRotationProven"] = observed_root_rotation_proven
current["remotePrekeyRootLastSeenAt"] = now
current["remotePrekeyRootNodeId"] = str(root_node_id or "")
current["remotePrekeyRootPublicKey"] = str(root_public_key or "")
current["remotePrekeyRootPublicKeyAlgo"] = str(root_public_key_algo or "Ed25519")
if not transparency_conflict:
current["remotePrekeySequence"] = observed_sequence
current["remotePrekeySignedAt"] = observed_signed_at
if observed_transparency_head and not transparency_conflict:
current["remotePrekeyTransparencyHead"] = observed_transparency_head
current["remotePrekeyTransparencySize"] = observed_transparency_size
current["remotePrekeyTransparencySeenAt"] = now
current["remotePrekeyTransparencyConflict"] = transparency_conflict
if witness_count is not None:
current["witness_count"] = max(0, int(witness_count or 0))
current["witness_checked_at"] = int(witness_latest_at or now)
prior_trust = str(current.get("trust_level", "") or "").strip()
trust_changed = False
if not pinned and invite_pinned:
current["remotePrekeyFingerprint"] = invite_pinned
current["remotePrekeyPinnedAt"] = int(current.get("invitePinnedAt", 0) or now)
pinned = invite_pinned
if not pinned_root and invite_pinned_root:
current["remotePrekeyRootFingerprint"] = invite_pinned_root
current["remotePrekeyRootManifestFingerprint"] = invite_pinned_root_manifest
current["remotePrekeyRootWitnessPolicyFingerprint"] = str(
current.get("invitePinnedRootWitnessPolicyFingerprint", "") or ""
).strip().lower()
current["remotePrekeyRootWitnessThreshold"] = int(current.get("invitePinnedRootWitnessThreshold", 0) or 0)
current["remotePrekeyRootWitnessCount"] = int(current.get("invitePinnedRootWitnessCount", 0) or 0)
current["remotePrekeyRootWitnessDomainCount"] = int(
current.get("invitePinnedRootWitnessDomainCount", 0) or 0
)
current["remotePrekeyRootManifestGeneration"] = int(current.get("invitePinnedRootManifestGeneration", 0) or 0)
current["remotePrekeyRootRotationProven"] = bool(
int(current.get("invitePinnedRootManifestGeneration", 0) or 0) <= 1
or current.get("invitePinnedRootRotationProven")
)
current["remotePrekeyRootPinnedAt"] = int(current.get("invitePinnedAt", 0) or now)
current["remotePrekeyRootNodeId"] = str(current.get("invitePinnedRootNodeId", "") or "")
current["remotePrekeyRootPublicKey"] = str(current.get("invitePinnedRootPublicKey", "") or "")
current["remotePrekeyRootPublicKeyAlgo"] = str(current.get("invitePinnedRootPublicKeyAlgo", "") or "")
pinned_root = invite_pinned_root
pinned_root_manifest = invite_pinned_root_manifest
if not pinned:
# First-seen fingerprint — TOFU pin.
current["remotePrekeyFingerprint"] = candidate
current["remotePrekeyPinnedAt"] = now
current["remotePrekeyMismatch"] = False
if observed_root:
current["remotePrekeyRootFingerprint"] = observed_root
current["remotePrekeyRootManifestFingerprint"] = observed_root_manifest
current["remotePrekeyRootWitnessPolicyFingerprint"] = observed_root_witness_policy
current["remotePrekeyRootWitnessThreshold"] = observed_root_witness_threshold
current["remotePrekeyRootWitnessCount"] = observed_root_witness_count
current["remotePrekeyRootWitnessDomainCount"] = observed_root_witness_domain_count
current["remotePrekeyRootManifestGeneration"] = observed_root_manifest_generation
current["remotePrekeyRootRotationProven"] = observed_root_rotation_proven
current["remotePrekeyRootPinnedAt"] = now
current["remotePrekeyRootMismatch"] = False
current["trust_level"] = "tofu_pinned"
elif pinned == candidate and (not pinned_root or not observed_root or pinned_root == observed_root):
# Same fingerprint — preserve existing trust level (tofu or sas_verified).
current["remotePrekeyMismatch"] = bool(transparency_conflict)
current["remotePrekeyRootMismatch"] = False
if observed_root:
current["remotePrekeyRootFingerprint"] = observed_root
current["remotePrekeyRootManifestFingerprint"] = observed_root_manifest
current["remotePrekeyRootWitnessPolicyFingerprint"] = observed_root_witness_policy
current["remotePrekeyRootWitnessThreshold"] = observed_root_witness_threshold
current["remotePrekeyRootWitnessCount"] = observed_root_witness_count
current["remotePrekeyRootWitnessDomainCount"] = observed_root_witness_domain_count
current["remotePrekeyRootManifestGeneration"] = observed_root_manifest_generation
current["remotePrekeyRootRotationProven"] = observed_root_rotation_proven
if transparency_conflict:
trust_changed = True
if prior_trust in ("invite_pinned", "sas_verified"):
current["trust_level"] = "continuity_broken"
else:
current["trust_level"] = "mismatch"
elif prior_trust in ("mismatch", "continuity_broken"):
current["remotePrekeyMismatch"] = True
current["remotePrekeyRootMismatch"] = prior_root_mismatch
current["remotePrekeyTransparencyConflict"] = prior_transparency_conflict
current["trust_level"] = prior_trust
elif prior_trust not in ("tofu_pinned", "invite_pinned", "sas_verified"):
current["trust_level"] = "invite_pinned" if invite_pinned and pinned == invite_pinned else "tofu_pinned"
else:
# Changed fingerprint — severity depends on prior verification.
trust_changed = True
root_changed = bool(observed_root and pinned_root and pinned_root != observed_root)
current["remotePrekeyMismatch"] = pinned != candidate
current["remotePrekeyRootMismatch"] = root_changed
if observed_root and not pinned_root:
current["remotePrekeyRootFingerprint"] = observed_root
current["remotePrekeyRootManifestFingerprint"] = observed_root_manifest
current["remotePrekeyRootWitnessPolicyFingerprint"] = observed_root_witness_policy
current["remotePrekeyRootWitnessThreshold"] = observed_root_witness_threshold
current["remotePrekeyRootWitnessCount"] = observed_root_witness_count
current["remotePrekeyRootWitnessDomainCount"] = observed_root_witness_domain_count
current["remotePrekeyRootManifestGeneration"] = observed_root_manifest_generation
current["remotePrekeyRootRotationProven"] = observed_root_rotation_proven
current["remotePrekeyRootPinnedAt"] = now
current["remotePrekeyRootMismatch"] = False
root_changed = False
if prior_trust in ("invite_pinned", "sas_verified") or bool(invite_pinned_root):
current["trust_level"] = "continuity_broken"
else:
current["trust_level"] = "mismatch"
current["updated_at"] = int(time.time())
contacts[peer_key] = _normalize_contact(current)
_write_contacts(contacts)
return {
"ok": True,
"peer_id": peer_key,
"trust_changed": trust_changed,
"trust_level": contacts[peer_key]["trust_level"],
"contact": contacts[peer_key],
}
def confirm_sas_verification(
peer_id: str,
sas_phrase: str,
*,
peer_ref: str = "",
words: int = 8,
) -> dict[str, Any]:
"""Record successful SAS verification for a contact.
Sets trust_level to sas_verified and updates legacy compat fields.
The contact must already be in a verifiable state (tofu_pinned,
invite_pinned, or sas_verified for idempotence). Rejects mismatch and
continuity_broken to prevent silent re-pin of a changed fingerprint.
"""
peer_key = str(peer_id or "").strip()
if not peer_key:
raise ValueError("peer_id required")
contacts = _read_contacts()
current = _normalize_contact(contacts.get(peer_key))
if not str(current.get("remotePrekeyFingerprint", "") or "").strip():
return {"ok": False, "detail": "no pinned fingerprint to verify"}
current_trust = str(current.get("trust_level", "") or "").strip()
if current_trust in ("mismatch", "continuity_broken"):
return {
"ok": False,
"trust_level": current_trust,
"detail": f"cannot verify: trust_level is {current_trust} — acknowledge the changed fingerprint first",
}
normalized_phrase = _normalize_sas_phrase(sas_phrase)
if not normalized_phrase:
return {
"ok": False,
"trust_level": current_trust or "unpinned",
"detail": "sas proof required",
}
expected = _derive_expected_contact_sas_phrase(
peer_key,
peer_ref=str(peer_ref or ""),
words=max(2, min(int(words or 8), 16)),
)
if not bool(expected.get("ok")):
return {
"ok": False,
"trust_level": current_trust or "unpinned",
"detail": str(expected.get("detail", "") or "sas phrase unavailable"),
}
expected_phrase = _normalize_sas_phrase(str(expected.get("phrase", "") or ""))
if normalized_phrase != expected_phrase:
return {
"ok": False,
"trust_level": current_trust or "unpinned",
"detail": "sas phrase mismatch",
}
now = int(time.time())
current["trust_level"] = "sas_verified"
current["verified"] = True
current["verify_inband"] = True
current["verified_at"] = now
current["remotePrekeyMismatch"] = False
current["remotePrekeyRootMismatch"] = False
current["verify_mismatch"] = False
current["updated_at"] = now
contacts[peer_key] = _normalize_contact(current)
_write_contacts(contacts)
try:
from services.mesh.mesh_wormhole_dead_drop import (
AliasRotationReason,
maybe_prepare_pairwise_dm_alias_rotation,
)
maybe_prepare_pairwise_dm_alias_rotation(
peer_id=peer_key,
peer_dh_pub=str(current.get("dhPubKey") or current.get("invitePinnedDhPubKey") or ""),
reason=AliasRotationReason.CONTACT_VERIFICATION_COMPLETED.value,
)
except Exception:
pass
return {
"ok": True,
"peer_id": peer_key,
"trust_level": "sas_verified",
"contact": contacts[peer_key],
}
def recover_verified_root_continuity(
peer_id: str,
sas_phrase: str,
*,
peer_ref: str = "",
words: int = 8,
) -> dict[str, Any]:
"""Explicitly adopt an observed stable-root change after SAS verification.
This is only valid for contacts in continuity_broken due to root mismatch.
It fetches the current bundle through the existing lookup path, verifies the
currently advertised root attestation still matches the observed mismatch,
then promotes the contact directly to sas_verified. Old invite-pinned trust
anchors are cleared because continuity is now rooted in SAS, not the prior
invite chain.
"""
peer_key = str(peer_id or "").strip()
if not peer_key:
raise ValueError("peer_id required")
contacts = _read_contacts()
current = _normalize_contact(contacts.get(peer_key))
current_trust = str(current.get("trust_level", "") or "").strip()
if current_trust != "continuity_broken":
return {
"ok": False,
"trust_level": current_trust,
"detail": f"root recovery only valid for continuity_broken, current is {current_trust}",
}
if not bool(current.get("remotePrekeyRootMismatch")):
return {
"ok": False,
"trust_level": current_trust,
"detail": "root recovery requires an observed stable root mismatch",
}
observed = str(current.get("remotePrekeyObservedFingerprint", "") or "").strip().lower()
observed_root = str(current.get("remotePrekeyObservedRootFingerprint", "") or "").strip().lower()
if not observed or not observed_root:
return {
"ok": False,
"trust_level": current_trust,
"detail": "no observed stable-root candidate to recover",
}
from services.mesh.mesh_wormhole_prekey import fetch_dm_prekey_bundle, verify_bundle_root_attestation
lookup_handle = str(current.get("invitePinnedPrekeyLookupHandle", "") or "").strip()
fetched = fetch_dm_prekey_bundle(agent_id="" if lookup_handle else peer_key, lookup_token=lookup_handle)
if not fetched.get("ok"):
return {
"ok": False,
"trust_level": current_trust,
"detail": str(fetched.get("detail", "") or "current prekey bundle unavailable for root recovery"),
}
current_bundle_root = verify_bundle_root_attestation(
{
"agent_id": str(fetched.get("agent_id", peer_key) or peer_key),
"bundle": dict(fetched.get("bundle") or {}),
"public_key": str(fetched.get("public_key", "") or ""),
"public_key_algo": str(fetched.get("public_key_algo", "Ed25519") or "Ed25519"),
"protocol_version": str(fetched.get("protocol_version", "") or ""),
}
)
if not current_bundle_root.get("ok"):
return {
"ok": False,
"trust_level": current_trust,
"detail": str(current_bundle_root.get("detail", "") or "root attestation invalid"),
}
fetched_fingerprint = str(fetched.get("trust_fingerprint", "") or "").strip().lower()
fetched_root = str(current_bundle_root.get("root_fingerprint", "") or "").strip().lower()
if fetched_fingerprint != observed or fetched_root != observed_root:
return {
"ok": False,
"trust_level": current_trust,
"detail": "observed root candidate changed again; refresh and compare SAS again before recovery",
}
normalized_phrase = _normalize_sas_phrase(sas_phrase)
if not normalized_phrase:
return {
"ok": False,
"trust_level": current_trust,
"detail": "sas proof required",
}
expected = _derive_expected_contact_sas_phrase(
peer_key,
peer_ref=str(peer_ref or ""),
words=max(2, min(int(words or 8), 16)),
peer_dh_pub_override=str(fetched.get("identity_dh_pub_key", "") or ""),
)
if not bool(expected.get("ok")):
return {
"ok": False,
"trust_level": current_trust,
"detail": str(expected.get("detail", "") or "sas phrase unavailable"),
}
expected_phrase = _normalize_sas_phrase(str(expected.get("phrase", "") or ""))
if normalized_phrase != expected_phrase:
return {
"ok": False,
"trust_level": current_trust,
"detail": "sas phrase mismatch",
}
now = int(time.time())
current["dhPubKey"] = str(fetched.get("identity_dh_pub_key", "") or "")
current["dhAlgo"] = str(fetched.get("dh_algo", "X25519") or "X25519")
current["remotePrekeyFingerprint"] = observed
current["remotePrekeyPinnedAt"] = now
current["remotePrekeyLastSeenAt"] = now
current["remotePrekeyMismatch"] = False
current["remotePrekeyRootFingerprint"] = observed_root
current["remotePrekeyObservedRootManifestFingerprint"] = str(
current_bundle_root.get("root_manifest_fingerprint", "") or ""
).strip().lower()
current["remotePrekeyRootManifestFingerprint"] = str(
current_bundle_root.get("root_manifest_fingerprint", "") or ""
).strip().lower()
current["remotePrekeyObservedRootWitnessPolicyFingerprint"] = str(
current_bundle_root.get("root_witness_policy_fingerprint", "") or ""
).strip().lower()
current["remotePrekeyRootWitnessPolicyFingerprint"] = str(
current_bundle_root.get("root_witness_policy_fingerprint", "") or ""
).strip().lower()
current["remotePrekeyObservedRootWitnessThreshold"] = int(
current_bundle_root.get("root_witness_threshold", 0) or 0
)
current["remotePrekeyRootWitnessThreshold"] = int(current_bundle_root.get("root_witness_threshold", 0) or 0)
current["remotePrekeyObservedRootWitnessCount"] = int(
current_bundle_root.get("root_witness_count", 0) or 0
)
current["remotePrekeyRootWitnessCount"] = int(current_bundle_root.get("root_witness_count", 0) or 0)
current["remotePrekeyObservedRootWitnessDomainCount"] = int(
current_bundle_root.get("root_witness_domain_count", 0) or 0
)
current["remotePrekeyRootWitnessDomainCount"] = int(
current_bundle_root.get("root_witness_domain_count", 0) or 0
)
current["remotePrekeyObservedRootManifestGeneration"] = int(
current_bundle_root.get("root_manifest_generation", 0) or 0
)
current["remotePrekeyRootManifestGeneration"] = int(current_bundle_root.get("root_manifest_generation", 0) or 0)
current["remotePrekeyObservedRootRotationProven"] = bool(
int(current_bundle_root.get("root_manifest_generation", 0) or 0) <= 1
or current_bundle_root.get("root_rotation_proven")
)
current["remotePrekeyRootRotationProven"] = bool(
int(current_bundle_root.get("root_manifest_generation", 0) or 0) <= 1
or current_bundle_root.get("root_rotation_proven")
)
current["remotePrekeyRootPinnedAt"] = now
current["remotePrekeyRootLastSeenAt"] = now
current["remotePrekeyRootNodeId"] = str(current_bundle_root.get("root_node_id", "") or "")
current["remotePrekeyRootPublicKey"] = str(current_bundle_root.get("root_public_key", "") or "")
current["remotePrekeyRootPublicKeyAlgo"] = str(
current_bundle_root.get("root_public_key_algo", "Ed25519") or "Ed25519"
)
current["remotePrekeyRootMismatch"] = False
current["invitePinnedTrustFingerprint"] = ""
current["invitePinnedNodeId"] = ""
current["invitePinnedPublicKey"] = ""
current["invitePinnedPublicKeyAlgo"] = ""
current["invitePinnedDhPubKey"] = ""
current["invitePinnedDhAlgo"] = ""
current["invitePinnedRootFingerprint"] = ""
current["invitePinnedRootManifestFingerprint"] = ""
current["invitePinnedRootWitnessPolicyFingerprint"] = ""
current["invitePinnedRootWitnessThreshold"] = 0
current["invitePinnedRootWitnessCount"] = 0
current["invitePinnedRootWitnessDomainCount"] = 0
current["invitePinnedRootManifestGeneration"] = 0
current["invitePinnedRootRotationProven"] = False
current["invitePinnedRootNodeId"] = ""
current["invitePinnedRootPublicKey"] = ""
current["invitePinnedRootPublicKeyAlgo"] = ""
current["invitePinnedIssuedAt"] = 0
current["invitePinnedExpiresAt"] = 0
current["invitePinnedAt"] = 0
current["trust_level"] = "sas_verified"
current["verified"] = True
current["verify_inband"] = True
current["verify_registry"] = False
current["verify_mismatch"] = False
current["verified_at"] = now
current["updated_at"] = now
contacts[peer_key] = _normalize_contact(current)
_write_contacts(contacts)
try:
from services.mesh.mesh_wormhole_dead_drop import (
AliasRotationReason,
maybe_prepare_pairwise_dm_alias_rotation,
)
maybe_prepare_pairwise_dm_alias_rotation(
peer_id=peer_key,
peer_dh_pub=str(current.get("dhPubKey") or current.get("invitePinnedDhPubKey") or ""),
reason=AliasRotationReason.CONTACT_VERIFICATION_COMPLETED.value,
)
except Exception:
pass
return {
"ok": True,
"peer_id": peer_key,
"trust_level": "sas_verified",
"detail": "stable root continuity recovered via SAS verification",
"contact": contacts[peer_key],
}
def acknowledge_changed_fingerprint(peer_id: str) -> dict[str, Any]:
"""Explicitly accept a changed observed fingerprint for a contact.
Valid only when trust_level is mismatch or continuity_broken and an
observed fingerprint exists. Re-pins the current observed fingerprint,
clears mismatch flags, clears legacy verified state, and sets
trust_level to tofu_pinned. This is NOT sas_verified — the operator
must re-confirm SAS separately.
"""
peer_key = str(peer_id or "").strip()
if not peer_key:
raise ValueError("peer_id required")
contacts = _read_contacts()
current = _normalize_contact(contacts.get(peer_key))
current_trust = str(current.get("trust_level", "") or "").strip()
if current_trust not in ("mismatch", "continuity_broken"):
return {
"ok": False,
"trust_level": current_trust,
"detail": f"acknowledgment only valid for mismatch or continuity_broken, current is {current_trust}",
}
observed = str(current.get("remotePrekeyObservedFingerprint", "") or "").strip().lower()
if not observed:
return {
"ok": False,
"trust_level": current_trust,
"detail": "no observed fingerprint to re-pin",
}
invite_pinned = str(current.get("invitePinnedTrustFingerprint", "") or "").strip().lower()
if invite_pinned and observed != invite_pinned:
return {
"ok": False,
"trust_level": current_trust,
"detail": "invite-pinned contact requires invite replacement before acknowledging changed fingerprint",
}
observed_root = str(current.get("remotePrekeyObservedRootFingerprint", "") or "").strip().lower()
observed_root_manifest = str(current.get("remotePrekeyObservedRootManifestFingerprint", "") or "").strip().lower()
invite_pinned_root = str(current.get("invitePinnedRootFingerprint", "") or "").strip().lower()
if bool(current.get("remotePrekeyRootMismatch")):
return {
"ok": False,
"trust_level": current_trust,
"detail": "stable root changed; recover root continuity with SAS or replace the signed invite before trusting this contact again",
}
if invite_pinned_root and observed_root and observed_root != invite_pinned_root:
return {
"ok": False,
"trust_level": current_trust,
"detail": "invite-pinned contact requires invite replacement before acknowledging changed stable root",
}
now = int(time.time())
current["remotePrekeyFingerprint"] = observed
current["remotePrekeyPinnedAt"] = now
current["remotePrekeyMismatch"] = False
if observed_root:
current["remotePrekeyRootFingerprint"] = observed_root
current["remotePrekeyRootManifestFingerprint"] = observed_root_manifest
current["remotePrekeyObservedRootManifestFingerprint"] = observed_root_manifest
current["remotePrekeyRootWitnessPolicyFingerprint"] = str(
current.get("remotePrekeyObservedRootWitnessPolicyFingerprint", "") or ""
).strip().lower()
current["remotePrekeyRootWitnessThreshold"] = int(
current.get("remotePrekeyObservedRootWitnessThreshold", 0) or 0
)
current["remotePrekeyRootWitnessCount"] = int(
current.get("remotePrekeyObservedRootWitnessCount", 0) or 0
)
current["remotePrekeyRootWitnessDomainCount"] = int(
current.get("remotePrekeyObservedRootWitnessDomainCount", 0) or 0
)
current["remotePrekeyRootManifestGeneration"] = int(
current.get("remotePrekeyObservedRootManifestGeneration", 0) or 0
)
current["remotePrekeyRootRotationProven"] = bool(
int(current.get("remotePrekeyObservedRootManifestGeneration", 0) or 0) <= 1
or current.get("remotePrekeyObservedRootRotationProven")
)
current["remotePrekeyRootPinnedAt"] = now
current["remotePrekeyRootMismatch"] = False
current["trust_level"] = "tofu_pinned"
current["verified"] = False
current["verify_inband"] = False
current["verify_mismatch"] = False
current["verified_at"] = 0
current["updated_at"] = now
contacts[peer_key] = _normalize_contact(current)
_write_contacts(contacts)
return {
"ok": True,
"peer_id": peer_key,
"trust_level": "tofu_pinned",
"contact": contacts[peer_key],
}