mirror of
https://github.com/sonr-io/crypto.git
synced 2026-01-12 04:09:13 +00:00
362 lines
9.5 KiB
Go
362 lines
9.5 KiB
Go
package wasm
|
|
|
|
import (
|
|
"crypto/ed25519"
|
|
"crypto/rand"
|
|
"encoding/base64"
|
|
"encoding/hex"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestSigner_NewSigner(t *testing.T) {
|
|
signer, err := NewSigner()
|
|
require.NoError(t, err)
|
|
require.NotNil(t, signer)
|
|
|
|
assert.NotNil(t, signer.privateKey)
|
|
assert.NotNil(t, signer.publicKey)
|
|
assert.Equal(t, ed25519.PrivateKeySize, len(signer.privateKey))
|
|
assert.Equal(t, ed25519.PublicKeySize, len(signer.publicKey))
|
|
}
|
|
|
|
func TestSigner_NewSignerFromPrivateKey(t *testing.T) {
|
|
// Generate a key pair
|
|
pub, priv, err := ed25519.GenerateKey(rand.Reader)
|
|
require.NoError(t, err)
|
|
|
|
// Create signer from private key
|
|
signer, err := NewSignerFromPrivateKey(priv)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, priv, signer.privateKey)
|
|
assert.Equal(t, pub, signer.publicKey)
|
|
|
|
// Test invalid key size
|
|
invalidKey := []byte("too short")
|
|
_, err = NewSignerFromPrivateKey(ed25519.PrivateKey(invalidKey))
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "invalid private key size")
|
|
}
|
|
|
|
func TestSigner_Sign(t *testing.T) {
|
|
signer, err := NewSigner()
|
|
require.NoError(t, err)
|
|
|
|
// Test data
|
|
wasmBytes := []byte("test wasm module content")
|
|
|
|
// Sign the data
|
|
signature, err := signer.Sign(wasmBytes)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, ed25519.SignatureSize, len(signature))
|
|
|
|
// Verify the signature
|
|
valid := ed25519.Verify(signer.publicKey, wasmBytes, signature)
|
|
assert.True(t, valid)
|
|
|
|
// Test signing different data produces different signature
|
|
differentData := []byte("different content")
|
|
signature2, err := signer.Sign(differentData)
|
|
require.NoError(t, err)
|
|
assert.NotEqual(t, signature, signature2)
|
|
}
|
|
|
|
func TestSignatureVerifier_AddTrustedKey(t *testing.T) {
|
|
verifier := NewSignatureVerifier()
|
|
|
|
// Generate a key pair
|
|
pub, _, err := ed25519.GenerateKey(rand.Reader)
|
|
require.NoError(t, err)
|
|
|
|
// Add trusted key
|
|
err = verifier.AddTrustedKey("test-key", pub)
|
|
assert.NoError(t, err)
|
|
|
|
// Test invalid key size
|
|
invalidKey := []byte("invalid")
|
|
err = verifier.AddTrustedKey("invalid-key", ed25519.PublicKey(invalidKey))
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "invalid public key size")
|
|
}
|
|
|
|
func TestSignatureVerifier_AddTrustedKeyFromHex(t *testing.T) {
|
|
verifier := NewSignatureVerifier()
|
|
|
|
// Generate a key pair
|
|
pub, _, err := ed25519.GenerateKey(rand.Reader)
|
|
require.NoError(t, err)
|
|
|
|
// Add key from hex
|
|
hexKey := hex.EncodeToString(pub)
|
|
err = verifier.AddTrustedKeyFromHex("hex-key", hexKey)
|
|
assert.NoError(t, err)
|
|
|
|
// Test invalid hex
|
|
err = verifier.AddTrustedKeyFromHex("bad-hex", "not-hex")
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestSignatureVerifier_Verify(t *testing.T) {
|
|
// Create signer and verifier
|
|
signer, err := NewSigner()
|
|
require.NoError(t, err)
|
|
|
|
verifier := NewSignatureVerifier()
|
|
|
|
// Test data
|
|
wasmBytes := []byte("test wasm module")
|
|
|
|
// Sign the data
|
|
signature, err := signer.Sign(wasmBytes)
|
|
require.NoError(t, err)
|
|
|
|
// Test verification without trusted keys
|
|
err = verifier.Verify(wasmBytes, signature)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "no trusted keys")
|
|
|
|
// Add trusted key
|
|
err = verifier.AddTrustedKey("signer1", signer.publicKey)
|
|
require.NoError(t, err)
|
|
|
|
// Test successful verification
|
|
err = verifier.Verify(wasmBytes, signature)
|
|
assert.NoError(t, err)
|
|
|
|
// Test verification with wrong data
|
|
wrongData := []byte("wrong data")
|
|
err = verifier.Verify(wrongData, signature)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "signature verification failed")
|
|
|
|
// Test verification with wrong signature
|
|
wrongSignature := make([]byte, ed25519.SignatureSize)
|
|
err = verifier.Verify(wasmBytes, wrongSignature)
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestSignatureVerifier_VerifyWithKey(t *testing.T) {
|
|
signer1, err := NewSigner()
|
|
require.NoError(t, err)
|
|
|
|
signer2, err := NewSigner()
|
|
require.NoError(t, err)
|
|
|
|
verifier := NewSignatureVerifier()
|
|
verifier.AddTrustedKey("key1", signer1.publicKey)
|
|
verifier.AddTrustedKey("key2", signer2.publicKey)
|
|
|
|
wasmBytes := []byte("test module")
|
|
signature1, _ := signer1.Sign(wasmBytes)
|
|
signature2, _ := signer2.Sign(wasmBytes)
|
|
|
|
// Verify with correct key
|
|
err = verifier.VerifyWithKey("key1", wasmBytes, signature1)
|
|
assert.NoError(t, err)
|
|
|
|
err = verifier.VerifyWithKey("key2", wasmBytes, signature2)
|
|
assert.NoError(t, err)
|
|
|
|
// Verify with wrong key
|
|
err = verifier.VerifyWithKey("key1", wasmBytes, signature2)
|
|
assert.Error(t, err)
|
|
|
|
// Verify with non-existent key
|
|
err = verifier.VerifyWithKey("key3", wasmBytes, signature1)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "trusted key not found")
|
|
}
|
|
|
|
func TestSignatureVerifier_Management(t *testing.T) {
|
|
verifier := NewSignatureVerifier()
|
|
|
|
// Generate keys
|
|
pub1, _, _ := ed25519.GenerateKey(rand.Reader)
|
|
pub2, _, _ := ed25519.GenerateKey(rand.Reader)
|
|
|
|
// Add keys
|
|
verifier.AddTrustedKey("key1", pub1)
|
|
verifier.AddTrustedKey("key2", pub2)
|
|
|
|
// Get key IDs
|
|
ids := verifier.GetTrustedKeyIDs()
|
|
assert.Len(t, ids, 2)
|
|
assert.Contains(t, ids, "key1")
|
|
assert.Contains(t, ids, "key2")
|
|
|
|
// Remove key
|
|
verifier.RemoveTrustedKey("key1")
|
|
ids = verifier.GetTrustedKeyIDs()
|
|
assert.Len(t, ids, 1)
|
|
assert.NotContains(t, ids, "key1")
|
|
assert.Contains(t, ids, "key2")
|
|
}
|
|
|
|
func TestSignedModule(t *testing.T) {
|
|
signer, err := NewSigner()
|
|
require.NoError(t, err)
|
|
|
|
module := []byte("test wasm module")
|
|
signerID := "test-signer"
|
|
version := "v1.0.0"
|
|
|
|
// Create signed module
|
|
signed, err := SignModule(signer, module, signerID, version)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, module, signed.Module)
|
|
assert.NotEmpty(t, signed.Hash)
|
|
assert.NotEmpty(t, signed.Signature)
|
|
assert.Equal(t, signerID, signed.SignerID)
|
|
assert.Equal(t, version, signed.Version)
|
|
assert.False(t, signed.Timestamp.IsZero())
|
|
|
|
// Verify signed module
|
|
verifier := NewSignatureVerifier()
|
|
verifier.AddTrustedKey(signerID, signer.publicKey)
|
|
|
|
err = VerifySignedModule(verifier, signed)
|
|
assert.NoError(t, err)
|
|
|
|
// Test with tampered module
|
|
signed.Module = []byte("tampered")
|
|
err = VerifySignedModule(verifier, signed)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "hash mismatch")
|
|
}
|
|
|
|
func TestSignatureManifest(t *testing.T) {
|
|
signer, err := NewSigner()
|
|
require.NoError(t, err)
|
|
|
|
module := []byte("test wasm module")
|
|
signerID := "manifest-signer"
|
|
|
|
// Create manifest
|
|
manifest, err := CreateSignatureManifest(module, signer, signerID)
|
|
require.NoError(t, err)
|
|
|
|
assert.NotEmpty(t, manifest.ModuleHash)
|
|
assert.Len(t, manifest.Signatures, 1)
|
|
assert.Len(t, manifest.TrustedKeys, 1)
|
|
assert.Equal(t, signerID, manifest.Signatures[0].SignerID)
|
|
assert.Equal(t, "Ed25519", manifest.Signatures[0].Algorithm)
|
|
assert.Equal(t, signerID, manifest.TrustedKeys[0].KeyID)
|
|
assert.Equal(t, "code-signing", manifest.TrustedKeys[0].Purpose)
|
|
|
|
// Verify with manifest
|
|
err = VerifyWithManifest(module, manifest)
|
|
assert.NoError(t, err)
|
|
|
|
// Test with wrong module
|
|
wrongModule := []byte("wrong module")
|
|
err = VerifyWithManifest(wrongModule, manifest)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "hash mismatch")
|
|
|
|
// Test with expired manifest
|
|
expired := time.Now().Add(-1 * time.Hour)
|
|
manifest.ExpiresAt = &expired
|
|
err = VerifyWithManifest(module, manifest)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "expired")
|
|
}
|
|
|
|
func TestManifestSerialization(t *testing.T) {
|
|
signer, err := NewSigner()
|
|
require.NoError(t, err)
|
|
|
|
module := []byte("test module")
|
|
manifest, err := CreateSignatureManifest(module, signer, "test-key")
|
|
require.NoError(t, err)
|
|
|
|
// Export manifest
|
|
data, err := ExportManifest(manifest)
|
|
require.NoError(t, err)
|
|
assert.NotEmpty(t, data)
|
|
|
|
// Import manifest
|
|
imported, err := ImportManifest(data)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, manifest.ModuleHash, imported.ModuleHash)
|
|
assert.Len(t, imported.Signatures, 1)
|
|
assert.Len(t, imported.TrustedKeys, 1)
|
|
|
|
// Verify imported manifest
|
|
err = VerifyWithManifest(module, imported)
|
|
assert.NoError(t, err)
|
|
|
|
// Test invalid JSON
|
|
_, err = ImportManifest([]byte("invalid json"))
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestMultipleSignatures(t *testing.T) {
|
|
// Create multiple signers
|
|
signer1, _ := NewSigner()
|
|
signer2, _ := NewSigner()
|
|
|
|
module := []byte("multi-signed module")
|
|
|
|
// Create manifest with first signature
|
|
manifest, err := CreateSignatureManifest(module, signer1, "signer1")
|
|
require.NoError(t, err)
|
|
|
|
// Add second signature
|
|
signature2, _ := signer2.Sign(module)
|
|
manifest.Signatures = append(manifest.Signatures, SignatureEntry{
|
|
Signature: base64.StdEncoding.EncodeToString(signature2),
|
|
SignerID: "signer2",
|
|
Timestamp: time.Now(),
|
|
Algorithm: "Ed25519",
|
|
})
|
|
|
|
manifest.TrustedKeys = append(manifest.TrustedKeys, TrustedKeyEntry{
|
|
KeyID: "signer2",
|
|
PublicKey: base64.StdEncoding.EncodeToString(signer2.GetPublicKey()),
|
|
AddedAt: time.Now(),
|
|
Purpose: "code-signing",
|
|
})
|
|
|
|
// Verify with either signature
|
|
err = VerifyWithManifest(module, manifest)
|
|
assert.NoError(t, err)
|
|
|
|
// Remove first signature and key
|
|
manifest.Signatures = manifest.Signatures[1:]
|
|
manifest.TrustedKeys = manifest.TrustedKeys[1:]
|
|
|
|
// Should still verify with second signature
|
|
err = VerifyWithManifest(module, manifest)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func BenchmarkSign(b *testing.B) {
|
|
signer, _ := NewSigner()
|
|
data := make([]byte, 1024*1024) // 1MB
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_, _ = signer.Sign(data)
|
|
}
|
|
}
|
|
|
|
func BenchmarkVerify(b *testing.B) {
|
|
signer, _ := NewSigner()
|
|
verifier := NewSignatureVerifier()
|
|
verifier.AddTrustedKey("bench", signer.publicKey)
|
|
|
|
data := make([]byte, 1024*1024) // 1MB
|
|
signature, _ := signer.Sign(data)
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = verifier.Verify(data, signature)
|
|
}
|
|
}
|