aboutsummaryrefslogtreecommitdiff
path: root/internal/slackware_com/crypto.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/slackware_com/crypto.go')
-rw-r--r--internal/slackware_com/crypto.go108
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
+}