added signed artifacts and SBOM generation capabilities
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
package signing_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/forgeo/forgebucket/internal/domain/signing"
|
||||
)
|
||||
|
||||
func TestGenerateAndSign(t *testing.T) {
|
||||
ks, err := signing.Generate()
|
||||
if err != nil {
|
||||
t.Fatalf("Generate: %v", err)
|
||||
}
|
||||
if ks.KeyID() == "" {
|
||||
t.Fatal("expected non-empty key ID")
|
||||
}
|
||||
if ks.PublicKeyPEM() == "" {
|
||||
t.Fatal("expected non-empty public key PEM")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSignAndVerify(t *testing.T) {
|
||||
ks, err := signing.Generate()
|
||||
if err != nil {
|
||||
t.Fatalf("Generate: %v", err)
|
||||
}
|
||||
|
||||
content := []byte("hello, forgebucket artifact")
|
||||
bundle, err := ks.Sign(42, "binary.tar.gz", content)
|
||||
if err != nil {
|
||||
t.Fatalf("Sign: %v", err)
|
||||
}
|
||||
|
||||
if bundle.MediaType != "application/vnd.forgebucket.signature.bundle+json" {
|
||||
t.Errorf("unexpected media type: %s", bundle.MediaType)
|
||||
}
|
||||
if bundle.Payload.ArtifactID != 42 {
|
||||
t.Errorf("artifact ID mismatch: got %d", bundle.Payload.ArtifactID)
|
||||
}
|
||||
if bundle.Payload.Name != "binary.tar.gz" {
|
||||
t.Errorf("name mismatch: got %s", bundle.Payload.Name)
|
||||
}
|
||||
if bundle.Payload.Digest == "" {
|
||||
t.Error("expected non-empty digest")
|
||||
}
|
||||
if bundle.Signature == "" {
|
||||
t.Error("expected non-empty signature")
|
||||
}
|
||||
|
||||
bundleJSON, err := json.Marshal(bundle)
|
||||
if err != nil {
|
||||
t.Fatalf("marshal bundle: %v", err)
|
||||
}
|
||||
|
||||
result, err := ks.Verify(bundleJSON)
|
||||
if err != nil {
|
||||
t.Fatalf("Verify: %v", err)
|
||||
}
|
||||
if !result.Valid {
|
||||
t.Error("expected valid=true")
|
||||
}
|
||||
if !result.KeyMatches {
|
||||
t.Error("expected keyMatchesServer=true")
|
||||
}
|
||||
if result.Digest != bundle.Payload.Digest {
|
||||
t.Errorf("digest mismatch: %s vs %s", result.Digest, bundle.Payload.Digest)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifyTamperedSignature(t *testing.T) {
|
||||
ks, _ := signing.Generate()
|
||||
content := []byte("artifact content")
|
||||
bundle, err := ks.Sign(1, "file.bin", content)
|
||||
if err != nil {
|
||||
t.Fatalf("Sign: %v", err)
|
||||
}
|
||||
|
||||
// Tamper: valid base64 but not a valid ECDSA signature over this payload.
|
||||
// "Z2FyYmFnZQ==" decodes to "garbage" which is not a valid DER ECDSA sig.
|
||||
bundle.Signature = "Z2FyYmFnZQ=="
|
||||
|
||||
bundleJSON, _ := json.Marshal(bundle)
|
||||
result, err := ks.Verify(bundleJSON)
|
||||
if err != nil {
|
||||
t.Fatalf("Verify should not error on invalid sig: %v", err)
|
||||
}
|
||||
if result.Valid {
|
||||
t.Error("expected valid=false for tampered signature")
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifyWrongKey(t *testing.T) {
|
||||
ks1, _ := signing.Generate()
|
||||
ks2, _ := signing.Generate()
|
||||
|
||||
content := []byte("artifact")
|
||||
bundle, err := ks1.Sign(10, "tool", content)
|
||||
if err != nil {
|
||||
t.Fatalf("Sign: %v", err)
|
||||
}
|
||||
|
||||
bundleJSON, _ := json.Marshal(bundle)
|
||||
|
||||
// Verify with ks2 — key won't match.
|
||||
result, err := ks2.Verify(bundleJSON)
|
||||
if err != nil {
|
||||
t.Fatalf("Verify: %v", err)
|
||||
}
|
||||
// Cryptographic signature is still valid (uses embedded pub key), but key doesn't match server.
|
||||
if !result.Valid {
|
||||
t.Error("signature itself should still be cryptographically valid")
|
||||
}
|
||||
if result.KeyMatches {
|
||||
t.Error("expected keyMatchesServer=false when signed by a different key")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewFromPEM(t *testing.T) {
|
||||
ks1, err := signing.Generate()
|
||||
if err != nil {
|
||||
t.Fatalf("Generate: %v", err)
|
||||
}
|
||||
|
||||
pemStr, err := ks1.PrivateKeyPEM()
|
||||
if err != nil {
|
||||
t.Fatalf("PrivateKeyPEM: %v", err)
|
||||
}
|
||||
|
||||
ks2, err := signing.New(pemStr)
|
||||
if err != nil {
|
||||
t.Fatalf("New from PEM: %v", err)
|
||||
}
|
||||
|
||||
if ks1.KeyID() != ks2.KeyID() {
|
||||
t.Errorf("key IDs differ: %s vs %s", ks1.KeyID(), ks2.KeyID())
|
||||
}
|
||||
|
||||
// Sign with ks1, verify with ks2 (same underlying key).
|
||||
bundle, _ := ks1.Sign(5, "bin", []byte("data"))
|
||||
bundleJSON, _ := json.Marshal(bundle)
|
||||
|
||||
result, err := ks2.Verify(bundleJSON)
|
||||
if err != nil {
|
||||
t.Fatalf("Verify: %v", err)
|
||||
}
|
||||
if !result.Valid {
|
||||
t.Error("expected valid=true")
|
||||
}
|
||||
if !result.KeyMatches {
|
||||
t.Error("expected keyMatchesServer=true for same key material")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user