cmd/age: initial support for SSH identities and recipients

Signed-off-by: Matt Layher <mdlayher@gmail.com>
This commit is contained in:
Matt Layher
2019-10-07 18:09:22 -04:00
committed by Filippo Valsorda
parent 7f61cf23bf
commit dd0939ffaa
3 changed files with 81 additions and 3 deletions

View File

@@ -13,6 +13,7 @@ import (
"io"
"log"
"os"
"path/filepath"
"time"
"github.com/FiloSottile/age/internal/age"
@@ -89,7 +90,17 @@ func decrypt() {
var identities []age.Identity
// TODO: use the default location if no arguments are provided.
for _, name := range flag.Args() {
ids, err := parseIdentitiesFile(name)
var (
ids []age.Identity
err error
)
// TODO: smarter detection logic than looking for .ssh/* in the path.
if filepath.Base(filepath.Dir(name)) == ".ssh" {
ids, err = parseSSHIdentity(name)
} else {
ids, err = parseIdentitiesFile(name)
}
if err != nil {
log.Fatalf("Error: %v", err)
}

View File

@@ -9,6 +9,8 @@ package main
import (
"bufio"
"fmt"
"io"
"io/ioutil"
"os"
"strings"
@@ -16,10 +18,14 @@ import (
)
func parseRecipient(arg string) (age.Recipient, error) {
if strings.HasPrefix(arg, "pubkey:") {
switch {
case strings.HasPrefix(arg, "pubkey:"):
return age.ParseX25519Recipient(arg)
case strings.HasPrefix(arg, "ssh-"):
return age.ParseSSHRecipient(arg)
}
return nil, fmt.Errorf("unknown recipient type: %s", arg)
return nil, fmt.Errorf("unknown recipient type: %q", arg)
}
func parseIdentitiesFile(name string) ([]age.Identity, error) {
@@ -50,3 +56,26 @@ func parseIdentitiesFile(name string) ([]age.Identity, error) {
}
return ids, nil
}
func parseSSHIdentity(name string) ([]age.Identity, error) {
f, err := os.Open(name)
if err != nil {
return nil, fmt.Errorf("failed to open file: %v", err)
}
defer f.Close()
// Don't allow unbounded reads.
// TODO: support for multiple keys in the same stream, such as user.keys
// on GitHub.
pemBytes, err := ioutil.ReadAll(io.LimitReader(f, 1<<20))
if err != nil {
return nil, fmt.Errorf("failed to read %q: %v", name, err)
}
id, err := age.ParseSSHIdentity(pemBytes)
if err != nil {
return nil, fmt.Errorf("malformed SSH identity in %q: %v", name, err)
}
return []age.Identity{id}, nil
}