Files
AnomalRoil ed54973318 Fixing GPG ID related issues (#3275)
* Adding regression test

Signed-off-by: Yolan Romailler <AnomalRoil@users.noreply.github.com>

* fixing recipient logic to honor subkeys

Signed-off-by: Yolan Romailler <AnomalRoil@users.noreply.github.com>

* Revert "Adding regression test"

This reverts commit fcb85c9d2ee4ce3b1d53f934338c6a33e18d7d9d.

Signed-off-by: Yolan Romailler <AnomalRoil@users.noreply.github.com>

* adding comment about noop

Signed-off-by: Yolan Romailler <AnomalRoil@users.noreply.github.com>

* Linting

Signed-off-by: Yolan Romailler <AnomalRoil@users.noreply.github.com>

* Addressing review comments

Signed-off-by: Yolan Romailler <AnomalRoil@users.noreply.github.com>

* avoid noise debug logs

Signed-off-by: Yolan Romailler <AnomalRoil@users.noreply.github.com>

---------

Signed-off-by: Yolan Romailler <AnomalRoil@users.noreply.github.com>
2025-10-08 15:14:19 +02:00

72 lines
2.1 KiB
Go

package cli
import (
"bytes"
"context"
"encoding/hex"
"errors"
"fmt"
"io"
"os"
"os/exec"
"github.com/gopasspw/gopass/internal/backend/crypto/gpg"
"github.com/gopasspw/gopass/internal/out"
"github.com/gopasspw/gopass/pkg/debug"
)
// Encrypt will encrypt the given content for the recipients. If alwaysTrust is true
// the trust-model will be set to always as to avoid (annoying) "unusable public key"
// errors when encrypting.
func (g *GPG) Encrypt(ctx context.Context, plaintext []byte, recipients []string) ([]byte, error) {
ctx, cancel := context.WithTimeout(ctx, Timeout)
defer cancel()
args := append(g.args, "--encrypt")
if gpg.IsAlwaysTrust(ctx) {
// changing the trustmodel is possibly dangerous. A user should always
// explicitly opt-in to do this
args = append(args, "--trust-model=always")
}
buf := &bytes.Buffer{}
if len(recipients) == 0 {
return buf.Bytes(), errors.New("recipients list is empty")
}
var badRecipients []string
for _, r := range recipients {
kl, err := g.listKeys(ctx, "public", r)
if err != nil {
debug.Log("Failed to check key %s. Adding anyway. %s", err)
} else if len(kl.UseableKeys(gpg.IsAlwaysTrust(ctx))) < 1 {
badRecipients = append(badRecipients, r)
errmsg := fmt.Sprintf("Not using invalid key %q for encryption. Check its expiration date, its encryption capabilities and trust.", r)
debug.Log(errmsg)
out.Printf(ctx, errmsg)
continue
}
debug.Log("adding recipient %s", r)
args = append(args, "--recipient", r)
}
if len(badRecipients) == len(recipients) {
return buf.Bytes(), errors.New("no valid and trusted recipients were found")
}
cmd := exec.CommandContext(ctx, g.binary, args...)
cmd.Stdin = bytes.NewReader(plaintext)
// the encrypted blob as an hexdump and errors are printed to the log file, and to stdout
hexLogger := hex.Dumper(debug.LogWriter)
cmd.Stdout = io.MultiWriter(buf, hexLogger)
cmd.Stderr = io.MultiWriter(os.Stderr, debug.LogWriter)
debug.V(1).Log("%s %+v", cmd.Path, cmd.Args)
err := cmd.Run()
_ = hexLogger.Close()
if err != nil {
debug.Log("GPG encrypt failed: %s %+v: %+v", cmd.Path, cmd.Args, err)
}
return buf.Bytes(), err
}