package secret import ( "testing" ) func TestValidateGPGKeyID(t *testing.T) { tests := []struct { name string keyID string wantErr bool }{ // Valid cases { name: "valid email address", keyID: "test@example.com", wantErr: false, }, { name: "valid email with dots and hyphens", keyID: "test.user-name@example-domain.co.uk", wantErr: false, }, { name: "valid email with plus", keyID: "test+tag@example.com", wantErr: false, }, { name: "valid short key ID (8 hex chars)", keyID: "ABCDEF12", wantErr: false, }, { name: "valid long key ID (16 hex chars)", keyID: "ABCDEF1234567890", wantErr: false, }, { name: "valid fingerprint (40 hex chars)", keyID: "ABCDEF1234567890ABCDEF1234567890ABCDEF12", wantErr: false, }, { name: "valid lowercase hex fingerprint", keyID: "abcdef1234567890abcdef1234567890abcdef12", wantErr: false, }, { name: "valid mixed case hex", keyID: "AbCdEf1234567890", wantErr: false, }, // Invalid cases { name: "empty key ID", keyID: "", wantErr: true, }, { name: "key ID with spaces", keyID: "test user@example.com", wantErr: true, }, { name: "key ID with semicolon (command injection)", keyID: "test@example.com; rm -rf /", wantErr: true, }, { name: "key ID with pipe (command injection)", keyID: "test@example.com | cat /etc/passwd", wantErr: true, }, { name: "key ID with backticks (command injection)", keyID: "test@example.com`whoami`", wantErr: true, }, { name: "key ID with dollar sign (command injection)", keyID: "test@example.com$(whoami)", wantErr: true, }, { name: "key ID with quotes", keyID: "test\"@example.com", wantErr: true, }, { name: "key ID with single quotes", keyID: "test'@example.com", wantErr: true, }, { name: "key ID with backslash", keyID: "test\\@example.com", wantErr: true, }, { name: "key ID with newline", keyID: "test@example.com\nrm -rf /", wantErr: true, }, { name: "key ID with carriage return", keyID: "test@example.com\rrm -rf /", wantErr: true, }, { name: "hex with invalid length (7 chars)", keyID: "ABCDEF1", wantErr: true, }, { name: "hex with invalid length (9 chars)", keyID: "ABCDEF123", wantErr: true, }, { name: "hex with non-hex characters", keyID: "ABCDEFGH", wantErr: true, }, { name: "mixed format (email with hex)", keyID: "test@ABCDEF12", wantErr: true, }, { name: "key ID with ampersand", keyID: "test@example.com & echo test", wantErr: true, }, { name: "key ID with redirect", keyID: "test@example.com > /tmp/test", wantErr: true, }, { name: "key ID with null byte", keyID: "test@example.com\x00", wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := validateGPGKeyID(tt.keyID) if (err != nil) != tt.wantErr { t.Errorf("validateGPGKeyID() error = %v, wantErr %v", err, tt.wantErr) } }) } } func TestValidateKeychainItemName(t *testing.T) { tests := []struct { name string itemName string wantErr bool }{ // Valid cases { name: "valid simple name", itemName: "my-secret-key", wantErr: false, }, { name: "valid name with dots", itemName: "com.example.app.key", wantErr: false, }, { name: "valid name with underscores", itemName: "my_secret_key_123", wantErr: false, }, { name: "valid alphanumeric", itemName: "Secret123Key", wantErr: false, }, { name: "valid with hyphen at start", itemName: "-my-key", wantErr: false, }, { name: "valid with dot at start", itemName: ".hidden-key", wantErr: false, }, // Invalid cases { name: "empty item name", itemName: "", wantErr: true, }, { name: "item name with spaces", itemName: "my secret key", wantErr: true, }, { name: "item name with semicolon", itemName: "key;rm -rf /", wantErr: true, }, { name: "item name with pipe", itemName: "key|cat /etc/passwd", wantErr: true, }, { name: "item name with backticks", itemName: "key`whoami`", wantErr: true, }, { name: "item name with dollar sign", itemName: "key$(whoami)", wantErr: true, }, { name: "item name with quotes", itemName: "key\"name", wantErr: true, }, { name: "item name with single quotes", itemName: "key'name", wantErr: true, }, { name: "item name with backslash", itemName: "key\\name", wantErr: true, }, { name: "item name with newline", itemName: "key\nname", wantErr: true, }, { name: "item name with carriage return", itemName: "key\rname", wantErr: true, }, { name: "item name with ampersand", itemName: "key&echo test", wantErr: true, }, { name: "item name with redirect", itemName: "key>/tmp/test", wantErr: true, }, { name: "item name with null byte", itemName: "key\x00name", wantErr: true, }, { name: "item name with parentheses", itemName: "key(test)", wantErr: true, }, { name: "item name with brackets", itemName: "key[test]", wantErr: true, }, { name: "item name with asterisk", itemName: "key*", wantErr: true, }, { name: "item name with question mark", itemName: "key?", wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := validateKeychainItemName(tt.itemName) if (err != nil) != tt.wantErr { t.Errorf("validateKeychainItemName() error = %v, wantErr %v", err, tt.wantErr) } }) } }