Skip to content

Commit

Permalink
Fix pinentry for GPG ssh-agent emulation (#24)
Browse files Browse the repository at this point in the history
  • Loading branch information
eth-p committed Apr 7, 2022
1 parent 1d7fbe6 commit 0503f3e
Showing 1 changed file with 27 additions and 5 deletions.
32 changes: 27 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ var (

emailRegex = regexp.MustCompile(`\"(?P<name>.*<(?P<email>.*)>)\"`)
keyIDRegex = regexp.MustCompile(`ID (?P<keyId>.*),`) // keyID should be of exactly 8 or 16 characters
sshKeyIDRegex = regexp.MustCompile(`SHA256:(?P<keyId>.*)`)

errEmptyResults = errors.New("no matching entry was found")
errMultipleMatches = errors.New("multiple entries matched the query")
Expand All @@ -59,6 +60,12 @@ var (
_ = flag.String("display", "", "Set the X display (unused)")
)

const (
expectedKeyLengthGPG = 8
expectedKeyLengthFullGPG = 16
expectedKeyLengthSSH = 43
)

// checkEntryInKeychain executes a search in the current keychain. The search configured to not
// return the Data stored in the Keychain, as a result this should not require any type of
// authentication.
Expand Down Expand Up @@ -243,18 +250,33 @@ func (c KeychainClient) Msg(pinentry.Settings) *common.Error {
func GetPIN(authFn AuthFunc, promptFn PromptFunc, logger *log.Logger) GetPinFunc {
return func(s pinentry.Settings) (string, *common.Error) {
matches := emailRegex.FindStringSubmatch(s.Desc)
name := strings.Split(matches[1], " <")[0]
email := matches[2]
name := ""
email := ""

if len(matches) > 2 {
name = strings.Split(matches[1], " <")[0]
email = matches[2]
}

keyID := ""

matches = keyIDRegex.FindStringSubmatch(s.Desc)
keyID := matches[1]
if len(matches) >= 2 {
keyID = matches[1]
} else {
matches = sshKeyIDRegex.FindStringSubmatch(s.Desc)
if len(matches) >= 1 {
keyID = matches[1]
name = "ssh"
email = keyID
}
}

// Drop the optional 0x prefix from keyID (--keyid-format)
// https://www.gnupg.org/documentation/manuals/gnupg/GPG-Configuration-Options.html
keyID = strings.TrimPrefix(keyID, "0x")

if len(keyID) != 8 && len(keyID) != 16 {
logger.Printf("Invalid keyID: %s", keyID)
if len(keyID) != expectedKeyLengthGPG && len(keyID) != expectedKeyLengthFullGPG && len(keyID) != expectedKeyLengthSSH {
return "", assuanError(fmt.Errorf("invalid keyID: %s", keyID))
}

Expand Down

0 comments on commit 0503f3e

Please sign in to comment.