/* * Copyright (c) 2026 Kaiy Ragur * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package e2ee_test import ( "bytes" "crypto/ed25519" "io" "testing" "github.com/neilalexander/yggmail/internal/utils" "github.com/neilalexander/yggmail/internal/utils/age" "github.com/neilalexander/yggmail/internal/utils/e2ee" ) func TestFullE2EECycle(t *testing.T) { _, senderPriv, _ := ed25519.GenerateKey(nil) senderPub := senderPriv.Public().(ed25519.PublicKey) _, recipientPriv, _ := ed25519.GenerateKey(nil) recipientPub := recipientPriv.Public().(ed25519.PublicKey) _, domainPriv, _ := ed25519.GenerateKey(nil) domainPub := domainPriv.Public().(ed25519.PublicKey) senderAddr := utils.CreateAddress(senderPub, domainPub) // например: userkey@domainkey original := []byte("From: " + senderAddr + "\r\nSubject: test\r\n\r\nHello world! Это тест.") encryptedReader, err := e2ee.EncryptFilter( bytes.NewReader(original), senderAddr, []ed25519.PublicKey{recipientPub}, func(data []byte) ([]byte, error) { return ed25519.Sign(senderPriv, data), nil }, func(w io.Writer, rcpt ...ed25519.PublicKey) (io.WriteCloser, error) { r, err := age.Recipient(rcpt...) if err != nil { return nil, err } return age.EncryptArmor(w, r...) }, ) if err != nil { t.Fatal("EncryptFilter failed:", err) } encryptedBytes, _ := io.ReadAll(encryptedReader) encryptedReader.Close() stored := bytes.NewReader(encryptedBytes) decryptor := func(r io.Reader) (io.Reader, error) { id, err := age.Identity(recipientPriv) if err != nil { return nil, err } return age.DecryptArmor(r, id) } decrypted, err := e2ee.DecryptFilter(stored, decryptor) if err != nil { t.Fatal("DecryptFilter failed:", err) } result, _ := io.ReadAll(decrypted) decrypted.Close() if !bytes.Contains(result, []byte("Hello world! Это тест.")) { t.Fatalf("Decryption failed, got:\n%s", string(result)) } if !bytes.Contains(result, []byte("Subject: test")) { t.Fatalf("Original headers lost, got:\n%s", string(result)) } t.Log("Full E2EE cycle OK. Decrypted body preview:\n", string(result[:200])) }