package crypto import ( "crypto/sha256" "encoding/base64" "encoding/json" "fmt" "chorus/pkg/config" ) type RoleCrypto struct { config *config.Config } func NewRoleCrypto(cfg *config.Config, _ interface{}, _ interface{}, _ interface{}) (*RoleCrypto, error) { if cfg == nil { return nil, fmt.Errorf("config cannot be nil") } return &RoleCrypto{config: cfg}, nil } func (rc *RoleCrypto) EncryptForRole(data []byte, role string) ([]byte, string, error) { if len(data) == 0 { return []byte{}, rc.fingerprint(data), nil } encoded := make([]byte, base64.StdEncoding.EncodedLen(len(data))) base64.StdEncoding.Encode(encoded, data) return encoded, rc.fingerprint(data), nil } func (rc *RoleCrypto) DecryptForRole(data []byte, role string, _ string) ([]byte, error) { if len(data) == 0 { return []byte{}, nil } decoded := make([]byte, base64.StdEncoding.DecodedLen(len(data))) n, err := base64.StdEncoding.Decode(decoded, data) if err != nil { return nil, err } return decoded[:n], nil } func (rc *RoleCrypto) EncryptContextForRoles(payload interface{}, roles []string, _ []string) ([]byte, error) { raw, err := json.Marshal(payload) if err != nil { return nil, err } encoded := make([]byte, base64.StdEncoding.EncodedLen(len(raw))) base64.StdEncoding.Encode(encoded, raw) return encoded, nil } func (rc *RoleCrypto) fingerprint(data []byte) string { sum := sha256.Sum256(data) return base64.StdEncoding.EncodeToString(sum[:]) } type StorageAccessController interface { CanStore(role, key string) bool CanRetrieve(role, key string) bool } type StorageAuditLogger interface { LogEncryptionOperation(role, key, operation string, success bool) LogDecryptionOperation(role, key, operation string, success bool) LogKeyRotation(role, keyID string, success bool, message string) LogError(message string) LogAccessDenial(role, key, operation string) } type KeyInfo struct { Role string KeyID string }