erste module drin.

zwischenstand: Architektur aktualisiert, TOFU implementiert,
This commit is contained in:
br committed 2026-10-01 22:22:13 +02:00
1 parent 9d5789c5d7
commit c8df9d7651
41 files changed
+6455 -36

No files matched your search

+110
View File
@@ -0,0 +1,110 @@
package auth
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/x509"
"encoding/pem"
"errors"
"os"
"path/filepath"
"testing"
)
func TestKeyFile_RoundTrip(t *testing.T) {
priv, err := GenerateKey()
if err != nil {
t.Fatal(err)
}
path := filepath.Join(t.TempDir(), "node.key")
if err := WritePrivateKey(path, priv); err != nil {
t.Fatalf("WritePrivateKey: %v", err)
}
info, err := os.Stat(path)
if err != nil {
t.Fatal(err)
}
if perm := info.Mode().Perm(); perm != 0o600 {
t.Errorf("Dateirechte %o, erwartet 600", perm)
}
got, err := ReadPrivateKey(path)
if err != nil {
t.Fatalf("ReadPrivateKey: %v", err)
}
if !got.Equal(priv) {
t.Error("gelesener Schlüssel weicht ab")
}
}
func TestWritePrivateKey_NeverOverwrites(t *testing.T) {
priv, _ := GenerateKey()
path := filepath.Join(t.TempDir(), "node.key")
if err := WritePrivateKey(path, priv); err != nil {
t.Fatal(err)
}
other, _ := GenerateKey()
if err := WritePrivateKey(path, other); !errors.Is(err, os.ErrExist) {
t.Errorf("erwartet os.ErrExist, bekommen %v", err)
}
if got, _ := ReadPrivateKey(path); !got.Equal(priv) {
t.Error("bestehender Schlüssel wurde überschrieben")
}
}
func TestReadPrivateKey_RejectsInsecurePermissions(t *testing.T) {
priv, _ := GenerateKey()
path := filepath.Join(t.TempDir(), "node.key")
if err := WritePrivateKey(path, priv); err != nil {
t.Fatal(err)
}
if err := os.Chmod(path, 0o644); err != nil {
t.Fatal(err)
}
if _, err := ReadPrivateKey(path); !errors.Is(err, ErrInsecureKeyFile) {
t.Errorf("erwartet ErrInsecureKeyFile, bekommen %v", err)
}
}
func TestReadPrivateKey_InvalidContent(t *testing.T) {
ecKey, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
ecDER, _ := x509.MarshalPKCS8PrivateKey(ecKey)
tests := map[string][]byte{
"kein PEM": []byte("hallo"),
"falscher Typ": pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: []byte{1, 2, 3}}),
"kaputtes PKCS8": pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: []byte{1, 2, 3}}),
"kein Ed25519": pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: ecDER}),
}
for name, content := range tests {
t.Run(name, func(t *testing.T) {
path := filepath.Join(t.TempDir(), "node.key")
if err := os.WriteFile(path, content, 0o600); err != nil {
t.Fatal(err)
}
if _, err := ReadPrivateKey(path); !errors.Is(err, ErrInvalidKey) {
t.Errorf("erwartet ErrInvalidKey, bekommen %v", err)
}
})
}
if _, err := ReadPrivateKey(filepath.Join(t.TempDir(), "fehlt.key")); !errors.Is(err, os.ErrNotExist) {
t.Errorf("fehlende Datei: erwartet os.ErrNotExist, bekommen %v", err)
}
}
func TestPublicKeyEncoding(t *testing.T) {
priv, _ := GenerateKey()
pub := priv.Public().(ed25519PublicKey)
enc := EncodePublicKey(pub)
got, err := DecodePublicKey(enc)
if err != nil {
t.Fatalf("DecodePublicKey: %v", err)
}
if !got.Equal(pub) {
t.Error("Round-Trip weicht ab")
}
for _, bad := range []string{"", "!!!", "AAAA"} {
if _, err := DecodePublicKey(bad); !errors.Is(err, ErrInvalidKey) {
t.Errorf("DecodePublicKey(%q): erwartet ErrInvalidKey, bekommen %v", bad, err)
}
}
}