diff --git a/cmd/pm/main.go b/cmd/pm/main.go index bbbcc0f..2376163 100644 --- a/cmd/pm/main.go +++ b/cmd/pm/main.go @@ -22,6 +22,7 @@ subcommands: export (e) -- export a public key to stdout import (i) -- import a public key from stdin list (ls) -- list configured key info + sign (s) -- sign a file ` func main() { @@ -34,10 +35,12 @@ func main() { if root == "" { root = "/usr/local" } + signID := os.Getenv("PM_PGP_ID") switch cmd { case "env", "environ": fmt.Printf("PM_ROOT=%q\n", root) + fmt.Printf("PM_PGP_ID=%q\n", signID) case "key", "keyring": if len(os.Args[1:]) < 2 { fatalf("pm keyring: insufficient args\n\nusage: %v", keyUsage) @@ -81,6 +84,13 @@ func main() { if err := keyring.Export(root, os.Stdout, email); err != nil { fatalf("exporting public key for %q: %v\n", email, err) } + case "sign", "s": + if signID == "" { + fatalf("must set PM_PGP_ID\n") + } + if err := keyring.Sign(root, signID, os.Stdin, os.Stdout); err != nil { + fatalf("signing: %v\n", err) + } case "i", "import": if err := keyring.Import(root, os.Stdin); err != nil { fatalf("importing key: %v\n", err) diff --git a/keyring/keyring.go b/keyring/keyring.go index d35ed8d..3ec5558 100644 --- a/keyring/keyring.go +++ b/keyring/keyring.go @@ -183,6 +183,27 @@ func Import(root string, w io.Reader) error { return nil } +// Sign takes an id and a reader and writes the signature for that id to sig. +func Sign(root, id string, in io.Reader, sig io.Writer) error { + if err := ensureDir(root); err != nil { + return errors.Wrap(err, "can't find or create pgp dir") + } + srn, prn := getNames(root) + secs, _, err := getELs(srn, prn) + if err != nil { + return errors.Wrap(err, "getting existing keyrings") + } + e, err := findKey(secs, id) + if err != nil { + return errors.Wrapf(err, "finding key %q", id) + } + if err := openpgp.ArmoredDetachSign(sig, e, in, nil); err != nil { + return errors.Wrap(err, "armored detach sign") + } + fmt.Fprintf(sig, "\n") + return nil +} + func pGPDir(root string) string { return filepath.Join(root, "var", "lib", "pm", "pgp") }