// Package dedup implementiert ARC-03: Dublettenerkennung für // archivierte E-Mails über einen Inhalts-Hash. Kombiniert bewusst NICHT // mit mail/internal/storage oder mail/internal/crypto — dieses Paket // kennt beide nicht, der Aufrufer (spätere Ingest-Tickets) ruft es VOR // mail/internal/crypto auf. package dedup import ( "bytes" "crypto/sha256" "encoding/hex" "fmt" "io" ) // HashAndBuffer berechnet den SHA-256-Inhalts-Hash von plaintext. // // Bekannter Fehler vermeiden (siehe ARC-03-Ticket): der Hash MUSS auf // dem Klartext berechnet werden, BEVOR mail/internal/crypto verschlüsselt // — ein Hash auf dem Chiffretext wäre bei jedem Import anders (neuer // DEK je Objekt, siehe ARC-02) und Dublettenerkennung würde vollständig // versagen. Reihenfolge: Mail/Anhang empfangen -> HashAndBuffer (dieses // Paket) -> verschlüsseln (ARC-02) -> ablegen. // // plaintext wird beim Hashen vollständig verbraucht — HashAndBuffer // liefert deshalb einen erneut lesbaren Reader mit demselben Inhalt für // den nachfolgenden Verschlüsselungsschritt zurück. func HashAndBuffer(plaintext io.Reader) (contentHash string, buffered io.Reader, err error) { var buf bytes.Buffer hasher := sha256.New() if _, err := io.Copy(hasher, io.TeeReader(plaintext, &buf)); err != nil { return "", nil, fmt.Errorf("dedup: klartext hashen: %w", err) } return hex.EncodeToString(hasher.Sum(nil)), &buf, nil }