chore: switch to encryptor module

This commit is contained in:
Jonas Kaninda
2024-10-13 14:33:54 +02:00
parent 6b8491cdc0
commit f0afc0f4e0
6 changed files with 45 additions and 187 deletions

View File

@@ -8,6 +8,7 @@ package pkg
import (
"fmt"
"github.com/jkaninda/encryptor"
"github.com/jkaninda/mysql-bkup/utils"
"github.com/robfig/cron/v3"
"github.com/spf13/cobra"
@@ -417,16 +418,30 @@ func ftpBackup(db *dbConfig, config *BackupConfig) {
}
func encryptBackup(config *BackupConfig) {
backupFile, err := os.ReadFile(filepath.Join(tmpPath, config.backupFileName))
outputFile := fmt.Sprintf("%s.%s", filepath.Join(tmpPath, config.backupFileName), gpgExtension)
if err != nil {
utils.Fatal("Error reading backup file: %s ", err)
}
if config.usingKey {
err := encryptWithGPGPublicKey(filepath.Join(tmpPath, config.backupFileName), config.publicKey)
utils.Info("Encrypting backup using public key...")
pubKey, err := os.ReadFile(config.publicKey)
if err != nil {
utils.Fatal("error during encrypting backup %v", err)
utils.Fatal("Error reading public key: %s ", err)
}
err = encryptor.EncryptWithPublicKey(backupFile, fmt.Sprintf("%s.%s", filepath.Join(tmpPath, config.backupFileName), gpgExtension), pubKey)
if err != nil {
utils.Fatal("Error encrypting backup file: %v ", err)
}
utils.Info("Encrypting backup using public key...done")
} else if config.passphrase != "" {
err := encryptWithGPG(filepath.Join(tmpPath, config.backupFileName), config.passphrase)
utils.Info("Encrypting backup using passphrase...")
err := encryptor.Encrypt(backupFile, outputFile, config.passphrase)
if err != nil {
utils.Fatal("error during encrypting backup %v", err)
}
utils.Info("Encrypting backup using passphrase...done")
}

View File

@@ -1,182 +0,0 @@
// Package pkg /
/*****
@author Jonas Kaninda
@license MIT License <https://opensource.org/licenses/MIT>
@Copyright © 2024 Jonas Kaninda
**/
package pkg
import (
"errors"
"fmt"
"github.com/ProtonMail/gopenpgp/v2/crypto"
"github.com/jkaninda/mysql-bkup/utils"
"os"
"strings"
)
// decryptWithGPG decrypts backup file using a passphrase
func decryptWithGPG(inputFile string, passphrase string) error {
utils.Info("Decrypting backup using passphrase...")
// Read the encrypted file
encFileContent, err := os.ReadFile(inputFile)
if err != nil {
return errors.New(fmt.Sprintf("Error reading encrypted file: %s", err))
}
// Define the passphrase used to encrypt the file
_passphrase := []byte(passphrase)
// Create a PGP message object from the encrypted file content
encryptedMessage := crypto.NewPGPMessage(encFileContent)
// Decrypt the message using the passphrase
plainMessage, err := crypto.DecryptMessageWithPassword(encryptedMessage, _passphrase)
if err != nil {
return errors.New(fmt.Sprintf("Error decrypting file: %s", err))
}
// Save the decrypted file (restore it)
err = os.WriteFile(RemoveLastExtension(inputFile), plainMessage.GetBinary(), 0644)
if err != nil {
return errors.New(fmt.Sprintf("Error saving decrypted file: %s", err))
}
utils.Info("Decrypting backup using passphrase...done")
utils.Info("Backup file decrypted successful!")
return nil
}
// encryptWithGPG encrypts backup using a passphrase
func encryptWithGPG(inputFile string, passphrase string) error {
utils.Info("Encrypting backup using passphrase...")
// Read the file to be encrypted
plainFileContent, err := os.ReadFile(inputFile)
if err != nil {
return errors.New(fmt.Sprintf("Error reading file: %s", err))
}
// Define the passphrase to encrypt the file
_passphrase := []byte(passphrase)
// Create a message object from the file content
message := crypto.NewPlainMessage(plainFileContent)
// Encrypt the message using the passphrase
encryptedMessage, err := crypto.EncryptMessageWithPassword(message, _passphrase)
if err != nil {
return errors.New(fmt.Sprintf("Error encrypting backup file: %s", err))
}
// Save the encrypted .tar file
err = os.WriteFile(fmt.Sprintf("%s.%s", inputFile, gpgExtension), encryptedMessage.GetBinary(), 0644)
if err != nil {
return errors.New(fmt.Sprintf("Error saving encrypted filee: %s", err))
}
utils.Info("Encrypting backup using passphrase...done")
utils.Info("Backup file encrypted successful!")
return nil
}
// encryptWithGPGPublicKey encrypts backup using a public key
func encryptWithGPGPublicKey(inputFile string, publicKey string) error {
utils.Info("Encrypting backup using public key...")
// Read the public key
pubKeyBytes, err := os.ReadFile(publicKey)
if err != nil {
return errors.New(fmt.Sprintf("Error reading public key: %s", err))
}
// Create a new keyring with the public key
publicKeyObj, err := crypto.NewKeyFromArmored(string(pubKeyBytes))
if err != nil {
return errors.New(fmt.Sprintf("Error parsing public key: %s", err))
}
keyRing, err := crypto.NewKeyRing(publicKeyObj)
if err != nil {
return errors.New(fmt.Sprintf("Error creating key ring: %v", err))
}
// Read the file to encryptWithGPGPublicKey
fileContent, err := os.ReadFile(inputFile)
if err != nil {
return errors.New(fmt.Sprintf("Error reading file: %v", err))
}
// encryptWithGPG the file
message := crypto.NewPlainMessage(fileContent)
encMessage, err := keyRing.Encrypt(message, nil)
if err != nil {
return errors.New(fmt.Sprintf("Error encrypting file: %v", err))
}
// Save the encrypted file
err = os.WriteFile(fmt.Sprintf("%s.%s", inputFile, gpgExtension), encMessage.GetBinary(), 0644)
if err != nil {
return errors.New(fmt.Sprintf("Error saving encrypted file: %v", err))
}
utils.Info("Encrypting backup using public key...done")
utils.Info("Backup file encrypted successful!")
return nil
}
// decryptWithGPGPrivateKey decrypts backup file using a private key and passphrase.
// privateKey GPG private key
// passphrase GPG passphrase
func decryptWithGPGPrivateKey(inputFile, privateKey, passphrase string) error {
utils.Info("Encrypting backup using private key...")
// Read the private key
priKeyBytes, err := os.ReadFile(privateKey)
if err != nil {
return errors.New(fmt.Sprintf("Error reading private key: %s", err))
}
// Read the password for the private key (if its password-protected)
password := []byte(passphrase)
// Create a key object from the armored private key
privateKeyObj, err := crypto.NewKeyFromArmored(string(priKeyBytes))
if err != nil {
return errors.New(fmt.Sprintf("Error parsing private key: %s", err))
}
// Unlock the private key with the password
if passphrase != "" {
// Unlock the private key with the password
_, err = privateKeyObj.Unlock(password)
if err != nil {
return errors.New(fmt.Sprintf("Error unlocking private key: %s", err))
}
}
// Create a new keyring with the private key
keyRing, err := crypto.NewKeyRing(privateKeyObj)
if err != nil {
return errors.New(fmt.Sprintf("Error creating key ring: %v", err))
}
// Read the encrypted file
encFileContent, err := os.ReadFile(inputFile)
if err != nil {
return errors.New(fmt.Sprintf("Error reading encrypted file: %s", err))
}
// decryptWithGPG the file
encryptedMessage := crypto.NewPGPMessage(encFileContent)
message, err := keyRing.Decrypt(encryptedMessage, nil, 0)
if err != nil {
return errors.New(fmt.Sprintf("Error decrypting file: %s", err))
}
// Save the decrypted file
err = os.WriteFile(RemoveLastExtension(inputFile), message.GetBinary(), 0644)
if err != nil {
return errors.New(fmt.Sprintf("Error saving decrypted file: %s", err))
}
utils.Info("Encrypting backup using public key...done")
fmt.Println("File successfully decrypted!")
return nil
}
func RemoveLastExtension(filename string) string {
if idx := strings.LastIndex(filename, "."); idx != -1 {
return filename[:idx]
}
return filename
}

View File

@@ -14,6 +14,7 @@ import (
"os"
"os/exec"
"path/filepath"
"strings"
"time"
)
@@ -211,3 +212,9 @@ func checkConfigFile(filePath string) (string, error) {
// Return an error if neither file exists
return "", fmt.Errorf("no config file found")
}
func RemoveLastExtension(filename string) string {
if idx := strings.LastIndex(filename, "."); idx != -1 {
return filename[:idx]
}
return filename
}

View File

@@ -7,6 +7,7 @@
package pkg
import (
"github.com/jkaninda/encryptor"
"github.com/jkaninda/mysql-bkup/utils"
"github.com/spf13/cobra"
"os"
@@ -68,24 +69,38 @@ func RestoreDatabase(db *dbConfig, conf *RestoreConfig) {
utils.Fatal("Error, file required")
}
extension := filepath.Ext(filepath.Join(tmpPath, conf.file))
rFile, err := os.ReadFile(filepath.Join(tmpPath, conf.file))
outputFile := RemoveLastExtension(filepath.Join(tmpPath, conf.file))
if err != nil {
utils.Fatal("Error reading backup file: %s ", err)
}
if extension == ".gpg" {
if conf.usingKey {
utils.Info("Decrypting backup using private key...")
utils.Warn("Backup decryption using a private key is not fully supported")
err := decryptWithGPGPrivateKey(filepath.Join(tmpPath, conf.file), conf.privateKey, conf.passphrase)
prKey, err := os.ReadFile(conf.privateKey)
if err != nil {
utils.Fatal("Error reading public key: %s ", err)
}
err = encryptor.DecryptWithPrivateKey(rFile, outputFile, prKey, conf.passphrase)
if err != nil {
utils.Fatal("error during decrypting backup %v", err)
}
utils.Info("Decrypting backup using private key...done")
} else {
if conf.passphrase == "" {
utils.Error("Error, passphrase or private key required")
utils.Fatal("Your file seems to be a GPG file.\nYou need to provide GPG keys. GPG_PASSPHRASE or GPG_PRIVATE_KEY environment variable is required.")
} else {
utils.Info("Decrypting backup using passphrase...")
//decryptWithGPG file
err := decryptWithGPG(filepath.Join(tmpPath, conf.file), conf.passphrase)
err := encryptor.Decrypt(rFile, outputFile, conf.passphrase)
if err != nil {
utils.Fatal("Error decrypting file %s %v", file, err)
}
utils.Info("Decrypting backup using passphrase...done")
//Update file name
conf.file = RemoveLastExtension(file)
}