From 1b1a7d1d0025394a5c8d5072813e2fd9058ccc91 Mon Sep 17 00:00:00 2001 From: Marcus Bohessef Date: Sat, 7 Feb 2026 10:54:21 -0300 Subject: [PATCH] Ajuste nas migrations --- .../internal/services/credentials_service.go | 55 ++++++++++++++++--- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/backend/internal/services/credentials_service.go b/backend/internal/services/credentials_service.go index 5515402..8f7f412 100644 --- a/backend/internal/services/credentials_service.go +++ b/backend/internal/services/credentials_service.go @@ -10,6 +10,7 @@ import ( "encoding/base64" "encoding/json" "encoding/pem" + "strings" "fmt" "os" "sync" @@ -92,10 +93,10 @@ func (s *CredentialsService) GetDecryptedKey(ctx context.Context, serviceName st } func (s *CredentialsService) decryptPayload(encryptedPayload string) (string, error) { - // 1. Decode Private Key from Env - rawPrivateKey, err := base64.StdEncoding.DecodeString(os.Getenv("RSA_PRIVATE_KEY_BASE64")) + // 1. Load Private Key bytes from env with fallbacks (base64, raw PEM, \n literals) + rawPrivateKey, err := getRawPrivateKeyBytes() if err != nil { - return "", fmt.Errorf("failed to decode env RSA private key: %w", err) + return "", fmt.Errorf("failed to obtain RSA private key: %w", err) } block, _ := pem.Decode(rawPrivateKey) @@ -214,11 +215,10 @@ func (s *CredentialsService) DeleteCredentials(ctx context.Context, serviceName // EncryptPayload encrypts a payload using the derived public key func (s *CredentialsService) EncryptPayload(payload string) (string, error) { - // 1. Decode Private Key from Env (to derive Public Key) - // In a real scenario, you might store Public Key separately, but we can derive it. - rawPrivateKey, err := base64.StdEncoding.DecodeString(os.Getenv("RSA_PRIVATE_KEY_BASE64")) + // 1. Load Private Key bytes from env with fallbacks (base64, raw PEM, \n literals) + rawPrivateKey, err := getRawPrivateKeyBytes() if err != nil { - return "", fmt.Errorf("failed to decode env RSA private key: %w", err) + return "", fmt.Errorf("failed to obtain RSA private key: %w", err) } block, _ := pem.Decode(rawPrivateKey) @@ -257,6 +257,47 @@ func (s *CredentialsService) EncryptPayload(payload string) (string, error) { return base64.StdEncoding.EncodeToString(ciphertext), nil } +// getRawPrivateKeyBytes attempts to load the RSA private key from the environment +// trying several fallbacks: +// 1) Treat env as base64 and decode +// 2) Treat env as a PEM string with literal "\n" escapes and replace them +// 3) Treat env as raw PEM +// 4) Trim and try base64 again +func getRawPrivateKeyBytes() ([]byte, error) { + env := os.Getenv("RSA_PRIVATE_KEY_BASE64") + if env == "" { + return nil, fmt.Errorf("RSA_PRIVATE_KEY_BASE64 environment variable is empty") + } + + // Try base64 decode first + if b, err := base64.StdEncoding.DecodeString(env); err == nil { + if block, _ := pem.Decode(b); block != nil { + return b, nil + } + // Return decoded bytes even if pem.Decode returned nil; parsing later will catch it + return b, nil + } + + // Try replacing literal \n with real newlines + envNew := strings.ReplaceAll(env, "\\n", "\n") + if block, _ := pem.Decode([]byte(envNew)); block != nil { + return []byte(envNew), nil + } + + // Try raw env as PEM + if block, _ := pem.Decode([]byte(env)); block != nil { + return []byte(env), nil + } + + // Trim and try base64 again + trimmed := strings.TrimSpace(env) + if b, err := base64.StdEncoding.DecodeString(trimmed); err == nil { + return b, nil + } + + return nil, fmt.Errorf("could not decode RSA private key from env (tried base64 and PEM variants)") +} + // BootstrapCredentials checks if credentials are in DB, if not, migrates from Env func (s *CredentialsService) BootstrapCredentials(ctx context.Context) error { // List of services and their env mapping