package slackware_com import ( "bytes" _ "embed" "io" "os" "os/exec" ) //go:embed "security@slackware.com.asc" var slackwareGPGKey string type GnuPGVerifier struct { w *io.PipeWriter result <-chan struct { bool error } } func RunSignatureVerifier(signature string) *GnuPGVerifier { var v GnuPGVerifier r, w := io.Pipe() v.w = w result := make(chan struct { bool error }, 1) v.result = result go v.executeCMD(result, r, signature) return &v } func (g *GnuPGVerifier) executeCMD(c chan<- struct { bool error }, r io.ReadCloser, signature string) { defer close(c) defer r.Close() sigFile, err := os.CreateTemp("", "gpg-signature.*") if err != nil { c <- struct { bool error }{false, err} return } defer sigFile.Close() defer os.Remove(sigFile.Name()) sigFile.WriteString(signature) sigFile.Close() var keyRing bytes.Buffer cmd := exec.Command("gpg2", "--dearmor") cmd.Stdin = bytes.NewBufferString(slackwareGPGKey) cmd.Stdout = &keyRing err = cmd.Run() if err != nil { c <- struct { bool error }{false, err} return } keyRingFile, err := os.CreateTemp("", "gpg-keyring.*.gpg") if err != nil { c <- struct { bool error }{false, err} return } defer keyRingFile.Close() defer os.Remove(keyRingFile.Name()) keyRingFile.Write(keyRing.Bytes()) keyRingFile.Close() cmd = exec.Command("gpg2", "--no-default-keyring", "--keyring", keyRingFile.Name(), "--verify", sigFile.Name(), "-", ) cmd.Stdin = r err = cmd.Run() c <- struct { bool error }{err == nil, err} } func (g *GnuPGVerifier) Write(buf []byte) (int, error) { return g.w.Write(buf) } func (g *GnuPGVerifier) IsValid() (bool, error) { g.w.Close() res := <-g.result return res.bool, res.error }