1package cli
2
3import (
4	"bufio"
5	"bytes"
6	"context"
7	"os"
8	"os/exec"
9	"strings"
10
11	"github.com/gopasspw/gopass/internal/out"
12	"github.com/gopasspw/gopass/pkg/debug"
13)
14
15// Decrypt will try to decrypt the given file
16func (g *GPG) Decrypt(ctx context.Context, ciphertext []byte) ([]byte, error) {
17	args := append(g.args, "--decrypt")
18	cmd := exec.CommandContext(ctx, g.binary, args...)
19	cmd.Stdin = bytes.NewReader(ciphertext)
20	cmd.Stderr = os.Stderr
21
22	debug.Log("%s %+v", cmd.Path, cmd.Args)
23	return cmd.Output()
24}
25
26// RecipientIDs returns a list of recipient IDs for a given file
27func (g *GPG) RecipientIDs(ctx context.Context, buf []byte) ([]string, error) {
28	_ = os.Setenv("LANGUAGE", "C")
29	recp := make([]string, 0, 5)
30
31	args := []string{"--batch", "--list-only", "--list-packets", "--no-default-keyring", "--secret-keyring", "/dev/null"}
32	cmd := exec.CommandContext(ctx, g.binary, args...)
33	cmd.Stdin = bytes.NewReader(buf)
34	debug.Log("%s %+v", cmd.Path, cmd.Args)
35
36	cmdout, err := cmd.CombinedOutput()
37	if err != nil {
38		return []string{}, err
39	}
40
41	scanner := bufio.NewScanner(bytes.NewBuffer(cmdout))
42	for scanner.Scan() {
43		line := strings.TrimSpace(scanner.Text())
44		debug.Log("GPG Output: %s", line)
45		if !strings.HasPrefix(line, ":pubkey enc packet:") {
46			continue
47		}
48		m := splitPacket(line)
49		if keyid, found := m["keyid"]; found {
50			kl, err := g.listKeys(ctx, "public", keyid)
51			if err != nil || len(kl) < 1 {
52				continue
53			}
54			recp = append(recp, kl[0].Fingerprint)
55		}
56	}
57
58	if g.throwKids {
59		// TODO shouldn't log here
60		out.Warningf(ctx, "gpg option throw-keyids is set. some features might not work.")
61	}
62	return recp, nil
63}
64