Adds pm key export
This commit is contained in:
parent
e18aee5b4f
commit
6f41544659
@ -19,6 +19,7 @@ const keyUsage = `pm keyring: interact with pm's OpenPGP keyring
|
|||||||
|
|
||||||
subcommands:
|
subcommands:
|
||||||
create (c) -- create a fresh keypair
|
create (c) -- create a fresh keypair
|
||||||
|
export (e) -- export a public key to stdout
|
||||||
list (ls) -- list configured key info
|
list (ls) -- list configured key info
|
||||||
`
|
`
|
||||||
|
|
||||||
@ -40,7 +41,7 @@ func main() {
|
|||||||
if len(os.Args[1:]) < 2 {
|
if len(os.Args[1:]) < 2 {
|
||||||
fatalf("pm keyring: insufficient args\n\nusage: %v", keyUsage)
|
fatalf("pm keyring: insufficient args\n\nusage: %v", keyUsage)
|
||||||
}
|
}
|
||||||
sub := os.Args[2]
|
sub, args := os.Args[2], os.Args[3:]
|
||||||
switch sub {
|
switch sub {
|
||||||
case "ls", "list":
|
case "ls", "list":
|
||||||
if err := keyring.ListKeys(root, os.Stdout); err != nil {
|
if err := keyring.ListKeys(root, os.Stdout); err != nil {
|
||||||
@ -71,6 +72,14 @@ func main() {
|
|||||||
if err := keyring.NewKeyPair(root, name, email); err != nil {
|
if err := keyring.NewKeyPair(root, name, email); err != nil {
|
||||||
fatalf("creating keypair: %v\n", err)
|
fatalf("creating keypair: %v\n", err)
|
||||||
}
|
}
|
||||||
|
case "export", "e":
|
||||||
|
if len(args) != 1 {
|
||||||
|
fatalf("missing email argument\n")
|
||||||
|
}
|
||||||
|
email := args[0]
|
||||||
|
if err := keyring.Export(root, os.Stdout, email); err != nil {
|
||||||
|
fatalf("exporting public key for %q: %v\n", email, err)
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
fatalf("unknown keyring subcommand: %q\n\nusage: %v", sub, keyUsage)
|
fatalf("unknown keyring subcommand: %q\n\nusage: %v", sub, keyUsage)
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"golang.org/x/crypto/openpgp"
|
"golang.org/x/crypto/openpgp"
|
||||||
|
"golang.org/x/crypto/openpgp/armor"
|
||||||
|
|
||||||
"mcquay.me/fs"
|
"mcquay.me/fs"
|
||||||
)
|
)
|
||||||
@ -102,6 +103,37 @@ func ListKeys(root string, w io.Writer) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Export prints pubkey information associated with email to w.
|
||||||
|
func Export(root string, w io.Writer, email string) error {
|
||||||
|
if err := ensureDir(root); err != nil {
|
||||||
|
return errors.Wrap(err, "can't find or create pgp dir")
|
||||||
|
}
|
||||||
|
srn, prn := getNames(root)
|
||||||
|
_, pubs, err := getELs(srn, prn)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "getting existing keyrings")
|
||||||
|
}
|
||||||
|
|
||||||
|
e, err := findKey(pubs, email)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "find key")
|
||||||
|
}
|
||||||
|
|
||||||
|
aw, err := armor.Encode(w, openpgp.PublicKeyType, nil)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "creating armor encoder")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := e.Serialize(aw); err != nil {
|
||||||
|
return errors.Wrap(err, "serializing key")
|
||||||
|
}
|
||||||
|
if err := aw.Close(); err != nil {
|
||||||
|
return errors.Wrap(err, "closing armor encoder")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(w, "\n")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func pGPDir(root string) string {
|
func pGPDir(root string) string {
|
||||||
return filepath.Join(root, "var", "lib", "pm", "pgp")
|
return filepath.Join(root, "var", "lib", "pm", "pgp")
|
||||||
}
|
}
|
||||||
@ -153,3 +185,30 @@ func getELs(secring, pubring string) (openpgp.EntityList, openpgp.EntityList, er
|
|||||||
}
|
}
|
||||||
return sr, pr, nil
|
return sr, pr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func findKey(el openpgp.EntityList, id string) (*openpgp.Entity, error) {
|
||||||
|
var e *openpgp.Entity
|
||||||
|
if strings.Contains(id, "@") {
|
||||||
|
es := openpgp.EntityList{}
|
||||||
|
for _, p := range el {
|
||||||
|
for _, v := range p.Identities {
|
||||||
|
if id == v.UserId.Email {
|
||||||
|
es = append(es, p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(es) == 1 {
|
||||||
|
return es[0], nil
|
||||||
|
}
|
||||||
|
if len(es) > 1 {
|
||||||
|
return nil, errors.New("too many keys matched; try searching by key id?")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for _, p := range el {
|
||||||
|
if id == p.PrimaryKey.KeyIdShortString() {
|
||||||
|
return p, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return e, fmt.Errorf("key %q not found", id)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user