1dc065f84a
Audits against https://github.com/marmot-protocol/marmot surfaced several deviations from the Marmot specs. This commit addresses them across three tiers. Wire-format / interop (Tier 1) - MarmotGroupData: bump CURRENT_VERSION to 3 (MIP-01 v3), add disappearing_message_secs field, validate version is supported, reject value 0 for the disappearing duration. - GroupEventEncryption: use empty AAD (ByteArray(0)) per MIP-03 instead of binding nostr_group_id. Callers updated. This is wire-breaking against the prior (non-compliant) encoder. - Mip01ImageCrypto: new helper with HKDF derivations for the group image encryption key (label "mip01-image-encryption-v2") and the Blossom upload keypair seed (label "mip01-blossom-upload-v2"). - MarmotOutboundProcessor: auto-apply NIP-40 expiration tag on kind:445 events when the group has disappearing_message_secs configured. Authorization / MLS (Tier 2) - MlsGroup helpers: memberIdentity/myIdentityHex/currentMarmotData/ isLocalAdmin/isLeafAdmin. - proposeSelfRemove / selfRemove: reject members listed in admin_pubkeys (MIP-01: admins must self-demote first). - MlsGroup.commit(): non-admin members may only commit a single self-Update or SelfRemove-only proposals; admin-depletion guard rejects commits that would leave the group without any admin. - MlsGroup.create(): install the RFC 9420 required_capabilities extension in the GroupContext and advertise marmot_group_data (0xF2EE) + self_remove (0x000A) in the creator's leaf capabilities. - MlsGroupManager.updateGroupExtensions: admin gate (relaxed during bootstrap when no admins are yet configured). - MlsGroupManager.memberIdentityHex: expose credential identity lookup. - MarmotInboundProcessor: after MLS decrypt, verify the inner Nostr event's pubkey matches the MLS sender's BasicCredential identity. Hardening (Tier 3) - Mip04IMetaTag: new Mip04ParseResult sealed class with explicit DeprecatedV1 variant. parseMip04 logs a security warning when it encounters mip04-v1 instead of silently returning null. - Mip04MediaEncryption: expose LEGACY_VERSION_V1 = "mip04-v1" constant. - MarmotWelcomeSender: new awaitCommitAck suspend parameter on wrapWelcome / wrapWelcomeBytes so callers can plumb the Commit ack wait through the sender (MIP-02 ordering requirement). Tests - MarmotMipComplianceTest covers MarmotGroupData v3 round-trip (with and without disappearing_message_secs), constructor/decoder validation of disappearing=0 and unsupported versions, Mip01ImageCrypto determinism and label separation, and Mip04ParseResult v2/v1/invalid classification. https://claude.ai/code/session_014N7vG2TPgEeh7sQTpyHjJZ