package service import ( "crypto" "crypto/rand" "crypto/rsa" "crypto/sha256" "crypto/x509" "encoding/base64" "encoding/pem" "os" "path/filepath" "strings" "testing" ) func setupTestKey(t *testing.T) (string, *rsa.PrivateKey) { t.Helper() key, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { t.Fatal(err) } dir := t.TempDir() path := filepath.Join(dir, "test_private.pem") keyBytes := x509.MarshalPKCS1PrivateKey(key) block := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: keyBytes} f, err := os.Create(path) if err != nil { t.Fatal(err) } pem.Encode(f, block) f.Close() return path, key } func TestNewCryptoService(t *testing.T) { path, _ := setupTestKey(t) svc, err := NewCryptoService(path) if err != nil { t.Fatalf("NewCryptoService error: %v", err) } if svc == nil { t.Fatal("CryptoService je nil") } } func TestNewCryptoService_InvalidPath(t *testing.T) { _, err := NewCryptoService("/nonexistent/path.pem") if err == nil { t.Error("ocekivana greska za nepostojeci fajl") } } func TestNewCryptoService_InvalidPEM(t *testing.T) { dir := t.TempDir() path := filepath.Join(dir, "bad.pem") os.WriteFile(path, []byte("not a pem file"), 0600) _, err := NewCryptoService(path) if err == nil { t.Error("ocekivana greska za nevalidan PEM") } } func TestSign_Format(t *testing.T) { path, _ := setupTestKey(t) svc, _ := NewCryptoService(path) sig, err := svc.Sign([]byte("test data")) if err != nil { t.Fatalf("Sign error: %v", err) } if !strings.HasPrefix(sig, "RSA-SHA256:") { t.Errorf("potpis nema RSA-SHA256: prefix: %s", sig) } // Verify base64 part is valid b64 := strings.TrimPrefix(sig, "RSA-SHA256:") _, err = base64.StdEncoding.DecodeString(b64) if err != nil { t.Errorf("base64 deo potpisa nije validan: %v", err) } } func TestSign_VerifyWithPublicKey(t *testing.T) { path, privKey := setupTestKey(t) svc, _ := NewCryptoService(path) data := []byte(`{"license_key":"LT-TEST-1234","product":"LIGHT_TICKET"}`) sig, err := svc.Sign(data) if err != nil { t.Fatal(err) } // Extract base64 signature b64 := strings.TrimPrefix(sig, "RSA-SHA256:") sigBytes, _ := base64.StdEncoding.DecodeString(b64) // Verify with public key hash := sha256.Sum256(data) err = rsa.VerifyPKCS1v15(&privKey.PublicKey, crypto.SHA256, hash[:], sigBytes) if err != nil { t.Errorf("potpis nije validan: %v", err) } } func TestSign_TamperedData(t *testing.T) { path, privKey := setupTestKey(t) svc, _ := NewCryptoService(path) data := []byte(`{"license_key":"LT-TEST-1234"}`) sig, _ := svc.Sign(data) b64 := strings.TrimPrefix(sig, "RSA-SHA256:") sigBytes, _ := base64.StdEncoding.DecodeString(b64) // Tamper with data tampered := []byte(`{"license_key":"LT-FAKE-9999"}`) hash := sha256.Sum256(tampered) err := rsa.VerifyPKCS1v15(&privKey.PublicKey, crypto.SHA256, hash[:], sigBytes) if err == nil { t.Error("tampered data ne sme proci verifikaciju") } } func TestPublicKeyPEM(t *testing.T) { path, _ := setupTestKey(t) svc, _ := NewCryptoService(path) pubPEM, err := svc.PublicKeyPEM() if err != nil { t.Fatal(err) } if !strings.Contains(pubPEM, "BEGIN PUBLIC KEY") { t.Error("public key PEM nema ocekivani header") } if !strings.Contains(pubPEM, "END PUBLIC KEY") { t.Error("public key PEM nema ocekivani footer") } }