diff options
Diffstat (limited to 'internal/slackware_com/crypto.go')
-rw-r--r-- | internal/slackware_com/crypto.go | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/internal/slackware_com/crypto.go b/internal/slackware_com/crypto.go new file mode 100644 index 0000000..60bdca2 --- /dev/null +++ b/internal/slackware_com/crypto.go @@ -0,0 +1,108 @@ +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 +} |