This function works fine on linux but for some reason on windows it always returns a file not found error pointing to the location of the temporary file. If i get the temporary file by its name and read it before encryption, the read is successful and correct, but when the encrypt command runs it returns the error. Also when i run the exact command that gpg is running it completes successfully.

OS: Windows 10 GPG: Gpg4win 4.1.0

Below is an excerpt from my code

func createTempFile(dir, prefix string) (*os.File, error) {
    tmpfile, err := os.CreateTemp(dir, prefix)
    if err != nil {
        return nil, err
    }
    return tmpfile, nil
}

func writeFile(filename string, data []byte, perm os.FileMode) error {
    file, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
    if err != nil {
        return err
    }
    defer file.Close()

    _, err = file.Write(data)
    return err
}
func (g *GPGModule) Encrypt(plaintext []byte) ([]byte, error) {
    tmpfile, err := createTempFile("", "gpg-encrypt-")
    if err != nil {
        return nil, err
    }
    defer os.Remove(tmpfile.Name())

    err = writeFile(tmpfile.Name(), plaintext, 0600)
    if err != nil {
        return nil, err
    }

    outputFile := fmt.Sprintf("%s.gpg", tmpfile.Name())
    defer os.Remove(outputFile)

    cmd := exec.Command(g.GPGPath, "--encrypt", "--armor", "--recipient", g.GPGID, "--output", outputFile, tmpfile.Name())
    errOutput, err := cmd.CombinedOutput()
    if err != nil {
        return nil, fmt.Errorf("GPG encryption failed: %v\nError Output: %s", err, string(errOutput))
    }

    return readFile(outputFile)
}

Please help me fix this as I am new to golang and am struggling with this error

I have tried everything i can think of and everything that pops up on google, nothing seems to be able to resolve this issue.

1

There are 1 best solutions below

2
On

The file not found error on windows is because you are using exec.Command to run this gpg exe but there's no reason to do this:

https://github.com/andrewarrow/clout-cli/blob/c17af37d539839979b8e94828f21e7895578d3ab/session/encryption.go#L18

Go has nice libs to encrypt built in so you can avoid shelling out:

import (
    "crypto/aes"
    "crypto/cipher"
    "crypto/md5"
    "encoding/hex"
    "fmt"
    "math/rand"
)