Ctrl K
ComunidadGuías…

internal/app/wallet/keys_test.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package wallet

import (
	"bytes"
	"encoding/hex"
	"os"
	"path/filepath"
	"testing"
)

// The master key file is written hex-encoded, so it has to be decoded on the way
// back in. Reading it as raw bytes made the wallet work on first boot, where the
// freshly generated key was still in hand, and fail on every boot afterwards --
// with a "corrupt key file" error that gave no hint the encoding was the problem.
// A deployment that had been restarted even once could not start its wallet.
func TestLoadOrCreateKeyCipherSurvivesRestart(t *testing.T) {
	path := filepath.Join(t.TempDir(), "keys.key")

	first, err := LoadOrCreateKeyCipher(path)
	if err != nil {
		t.Fatalf("first load: %v", err)
	}
	if first == nil {
		t.Fatal("first load returned no cipher")
	}

	// The file must exist with the documented permissions.
	info, err := os.Stat(path)
	if err != nil {
		t.Fatal(err)
	}
	if info.Mode().Perm()&0077 != 0 {
		t.Fatalf("key file mode = %v, want no group or world bits", info.Mode().Perm())
	}

	// Second load reads the file back off disk -- this is the boot that used to fail.
	second, err := LoadOrCreateKeyCipher(path)
	if err != nil {
		t.Fatalf("reload after restart: %v", err)
	}
	if second == nil {
		t.Fatal("reload returned no cipher")
	}

	// Same key, so data sealed by the first cipher must open with the second.
	plaintext := []byte("address-and-key-material")
	sealed, nonce, err := first.Seal(plaintext)
	if err != nil {
		t.Fatalf("seal: %v", err)
	}
	opened, err := second.Open(sealed, nonce)
	if err != nil {
		t.Fatalf("open sealed data after restart: %v", err)
	}
	if !bytes.Equal(opened, plaintext) {
		t.Fatalf("opened %q, want %q", opened, plaintext)
	}
}

// Whatever is on disk has to come back as 32 bytes, which is the only shape
// newKeyCipher accepts.
func TestDecodeKeyFileRoundTrip(t *testing.T) {
	raw := make([]byte, 32)
	for i := range raw {
		raw[i] = byte(i)
	}
	for name, onDisk := range map[string][]byte{
		"hex with newline": []byte(hex.EncodeToString(raw) + "\n"),
		"hex no newline":   []byte(hex.EncodeToString(raw)),
	} {
		got := decodeKeyFile("x", onDisk)
		if len(got) != 32 {
			t.Fatalf("%s: decoded to %d bytes, want 32", name, len(got))
		}
		if !bytes.Equal(got, raw) {
			t.Fatalf("%s: decoded to the wrong key", name)
		}
	}
}

// A group-readable key file is a real disclosure, so the mode check has to hold
// on reload too, not just at creation.
func TestLoadOrCreateKeyCipherRejectsPermissiveFile(t *testing.T) {
	path := filepath.Join(t.TempDir(), "keys.key")
	raw := make([]byte, 32)
	if err := os.WriteFile(path, []byte(hex.EncodeToString(raw)+"\n"), 0640); err != nil {
		t.Fatal(err)
	}
	if _, err := LoadOrCreateKeyCipher(path); err == nil {
		t.Fatal("a 0640 master key file was accepted")
	}
}

func TestDecodeKeyFileRejectsUnpublishedRawEncoding(t *testing.T) {
	if decoded := decodeKeyFile("unused", bytes.Repeat([]byte{7}, 32)); decoded != nil {
		t.Fatal("accepted an unsupported raw-key encoding")
	}
}