111 lines
3.1 KiB
Go
111 lines
3.1 KiB
Go
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)
|
|
}
|
|
}
|
|
}
|