package crypto import ( "errors" "strings" "testing" ) func TestFingerprint_ParseRoundTrip(t *testing.T) { sc, err := LoadOrCreateServerCert(t.TempDir()) if err != nil { t.Fatal(err) } got, err := ParseFingerprint(string(sc.Fingerprint)) if err != nil || got != sc.Fingerprint { t.Errorf("ParseFingerprint = %q, %v", got, err) } for _, bad := range []string{"", "abc", strings.Repeat("A", 42), strings.Repeat("A", 44), strings.Repeat("+", 43), "sha256:" + string(sc.Fingerprint)} { if _, err := ParseFingerprint(bad); !errors.Is(err, ErrInvalidFingerprint) { t.Errorf("ParseFingerprint(%q): erwartet ErrInvalidFingerprint, bekommen %v", bad, err) } } } func TestEnrollmentToken_RoundTrip(t *testing.T) { sc, _ := LoadOrCreateServerCert(t.TempDir()) tok, err := NewEnrollmentToken(sc.Fingerprint) if err != nil { t.Fatalf("NewEnrollmentToken: %v", err) } s := tok.String() if !strings.HasPrefix(s, TokenPrefix) { t.Errorf("Token %q ohne Präfix %q", s, TokenPrefix) } if !strings.HasPrefix(tok.Secret, TokenPrefix) || strings.Contains(tok.Secret, ".") { t.Errorf("Secret %q: erwartet Präfix und keinen Fingerprint-Anteil", tok.Secret) } parsed, err := ParseEnrollmentToken(s) if err != nil { t.Fatalf("ParseEnrollmentToken: %v", err) } if parsed != tok { t.Errorf("Round-Trip weicht ab: %+v vs %+v", parsed, tok) } if parsed2, _ := ParseEnrollmentToken(" " + s + "\n"); parsed2 != tok { t.Error("Leerraum beim Kopieren sollte toleriert werden") } } func TestEnrollmentToken_Unique(t *testing.T) { sc, _ := LoadOrCreateServerCert(t.TempDir()) seen := map[string]bool{} for range 100 { tok, err := NewEnrollmentToken(sc.Fingerprint) if err != nil { t.Fatal(err) } if seen[tok.Secret] { t.Fatal("doppeltes Secret") } seen[tok.Secret] = true } } func TestEnrollmentToken_Errors(t *testing.T) { sc, _ := LoadOrCreateServerCert(t.TempDir()) good, _ := NewEnrollmentToken(sc.Fingerprint) secretPart := strings.TrimPrefix(good.Secret, TokenPrefix) fp := string(sc.Fingerprint) tests := map[string]string{ "leer": "", "falsches Präfix": "sltn_token_" + secretPart + "." + fp, "ohne Fingerprint": good.Secret, "leerer Fingerprint": good.Secret + ".", "kaputter Fingerprint": good.Secret + ".xyz", "Secret zu kurz": TokenPrefix + "abc." + fp, "Secret kein base64url": TokenPrefix + strings.Repeat("!", 43) + "." + fp, "zu viele Teile": good.String() + ".extra", } for name, s := range tests { t.Run(name, func(t *testing.T) { if _, err := ParseEnrollmentToken(s); !errors.Is(err, ErrInvalidToken) { t.Errorf("erwartet ErrInvalidToken, bekommen %v", err) } }) } if _, err := NewEnrollmentToken("kaputt"); !errors.Is(err, ErrInvalidFingerprint) { t.Errorf("NewEnrollmentToken mit kaputtem Fingerprint: %v", err) } }