Ctrl K
ComunidadGuías…

internal/crypto/crypto_test.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package crypto

import (
	"crypto"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha256"
	"crypto/x509"
	"encoding/base64"
	"encoding/pem"
	"strings"
	"testing"
)

func TestCreateHash(t *testing.T) {
	data := []byte("test data")
	tests := []struct {
		name      string
		algorithm string
		encoding  string
		expectErr bool
	}{
		{"SHA256 Hex", "sha256", "hex", false},
		{"SHA512 Base64", "sha512", "base64", false},
		{"MD5 Hex", "md5", "hex", false},
		{"Unsupported Algorithm", "sha1", "hex", true},
		{"Unsupported Encoding", "sha256", "binary", true},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			hash, err := CreateHash(data, tt.algorithm, tt.encoding)
			if (err != nil) != tt.expectErr {
				t.Errorf("unexpected error: %v", err)
			}
			if !tt.expectErr && hash == "" {
				t.Errorf("expected non-empty hash")
			}
		})
	}
}

func TestConvertSHA256HashToUUID(t *testing.T) {
	input := "1234567890abcdef1234567890abcdef12345678"
	expected := "12345678-90ab-cdef-1234-567890abcdef"
	result := ConvertSHA256HashToUUID(input)
	if result != expected {
		t.Errorf("expected %s, got %s", expected, result)
	}

	shortInput := "short"
	result = ConvertSHA256HashToUUID(shortInput)
	if result != "" {
		t.Errorf("expected empty string for short input, got %s", result)
	}
}

func TestGetBase64URLEncoding(t *testing.T) {
	input := base64.StdEncoding.EncodeToString([]byte("test data"))
	expected := strings.ReplaceAll(strings.ReplaceAll(input, "+", "-"), "/", "_")
	expected = strings.TrimRight(expected, "=")
	result := GetBase64URLEncoding(input)
	if result != expected {
		t.Errorf("expected %s, got %s", expected, result)
	}
}

func TestSignRSASHA256(t *testing.T) {
	data := "test data"

	privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
	if err != nil {
		t.Fatalf("failed to generate private key: %v", err)
	}

	privateKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey)
	privateKeyPEM := pem.EncodeToMemory(&pem.Block{
		Type:  "RSA PRIVATE KEY",
		Bytes: privateKeyBytes,
	})

	signature, err := SignRSASHA256(data, string(privateKeyPEM))
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	signatureBytes, err := base64.StdEncoding.DecodeString(signature)
	if err != nil {
		t.Fatalf("failed to decode signature: %v", err)
	}

	hash := sha256.Sum256([]byte(data))
	err = rsa.VerifyPKCS1v15(&privateKey.PublicKey, crypto.SHA256, hash[:], signatureBytes)
	if err != nil {
		t.Errorf("signature verification failed: %v", err)
	}

	invalidPEM := "-----BEGIN PRIVATE KEY-----\ninvalid\n-----END PRIVATE KEY-----"
	_, err = SignRSASHA256(data, invalidPEM)
	if err == nil {
		t.Errorf("expected error for invalid private key, got none")
	}
}

func TestSealUnsealAESGCMRoundTrip(t *testing.T) {
	masterKey := []byte("0123456789abcdef0123456789abcdef")
	plaintext := []byte("-----BEGIN RSA PRIVATE KEY-----\nsecret\n-----END RSA PRIVATE KEY-----")
	aad := []byte("app-1|private")

	sealed, err := SealAESGCM(plaintext, masterKey, aad)
	if err != nil {
		t.Fatalf("failed to seal: %v", err)
	}
	opened, err := UnsealAESGCM(sealed, masterKey, aad)
	if err != nil {
		t.Fatalf("failed to unseal with the matching aad: %v", err)
	}
	if string(opened) != string(plaintext) {
		t.Error("plaintext did not survive the seal/unseal round trip")
	}
}

// The property the aad exists for: a blob is only openable under the exact
// context it was sealed with, even though the master key is the same.
func TestUnsealAESGCMRejectsMismatchedAAD(t *testing.T) {
	masterKey := []byte("0123456789abcdef0123456789abcdef")
	sealed, err := SealAESGCM([]byte("app one private key"), masterKey, []byte("app-1|private"))
	if err != nil {
		t.Fatalf("failed to seal: %v", err)
	}

	for _, aad := range [][]byte{
		[]byte("app-2|private"), // same half, another app
		[]byte("app-1|public"),  // same app, other half
		nil,                     // no context at all
	} {
		if _, err := UnsealAESGCM(sealed, masterKey, aad); err == nil {
			t.Errorf("expected unseal to fail under aad %q, got nil", aad)
		}
	}
}

func TestSealAESGCMNilAADRoundTrips(t *testing.T) {
	masterKey := []byte("0123456789abcdef0123456789abcdef")
	sealed, err := SealAESGCM([]byte("unbound"), masterKey, nil)
	if err != nil {
		t.Fatalf("failed to seal: %v", err)
	}
	opened, err := UnsealAESGCM(sealed, masterKey, nil)
	if err != nil {
		t.Fatalf("failed to unseal: %v", err)
	}
	if string(opened) != "unbound" {
		t.Error("nil-aad payload did not survive the round trip")
	}
}

func TestUnsealAESGCMRejectsWrongMasterKey(t *testing.T) {
	aad := []byte("app-1|private")
	sealed, err := SealAESGCM([]byte("secret"), []byte("0123456789abcdef0123456789abcdef"), aad)
	if err != nil {
		t.Fatalf("failed to seal: %v", err)
	}
	if _, err := UnsealAESGCM(sealed, []byte("fedcba9876543210fedcba9876543210"), aad); err == nil {
		t.Error("expected unseal to fail under a different master key, got nil")
	}
}