Open stffndtz opened 2 years ago
@stffndtz can you give it a try to the latest release (v0.0.3) and check if it fixes the issue?
@jorgelbg It seems I am still getting the same error after the update:
echo "GETPIN" | pinentry-touchid
OK Hi from pinentry-touchid!
D hello
OK
Pinentry Serve returned error: EOF
Post update (via brew) I ran
/usr/local/opt/pinentry-touchid/bin/pinentry-touchid -fix && gpg-connect-agent reloadagent /bye
Let me know if I can help!
I have the same issue. I can use pinentry-touchid
for gpg-agent
, but I cannot use it generally for other programs.
$ echo GETPIN | pinentry-touchid
OK Hi from pinentry-touchid!
D abc
OK
Pinentry Serve returned error: EOF
Could this be the culprit?
Note the response from pinentry-mac
is not Hi from pinentry-mac!
. In fact it is Pleased to meet you
. Viz.
$ echo GETPIN | pinentry-mac
OK Pleased to meet you
D abc
OK
So maybe line 428
should be changed to:
if err := pinentry.Serve(callbacks, "Pleased to meet you"); err != nil {
I am just guessing.
Just to be clear, if you are only checking directly with:
$ echo GETPIN | pinentry-touchid
This is rightfully showing the pinentry-mac GUI. This happens because you haven't followed the full assuan protocol to talk to pinentry. Yes, GETPIN
is a valid assuan command that pinentry-touchid understands but since no information about your GPG key has been provided, it assumes that there is no item in the keychain and asks you to provide one (as a fallback mechanism).
You need to set pinentry-touchid as your pinentry-program in ~/.gnupg/gpg-agent.conf
by adding the following line:
pinentry-program /usr/local/bin/pinentry-touchid
and also reload your gpg-agent:
$ gpg-connect-agent reloadagent /bye
For checking that it is working you can use:
$ echo 1234 | gpg -as -
You can also interact directly via stdin with pinentry-touchid, but you need to do the full dance of providing the potions that the gpg-agent usually sends to any pinentry program.
Just to be clear, if you are only checking directly with:
$ echo GETPIN | pinentry-touchid
This is rightfully showing the pinentry-mac GUI. This happens because you haven't followed the full assuan protocol to talk to pinentry. Yes,
GETPIN
is a valid assuan command that pinentry-touchid understands but since no information about your GPG key has been provided, it assumes that there is no item in the keychain and asks you to provide one (as a fallback mechanism).You need to set pinentry-touchid as your pinentry-program in
~/.gnupg/gpg-agent.conf
by adding the following line:pinentry-program /usr/local/bin/pinentry-touchid
and also reload your gpg-agent:
$ gpg-connect-agent reloadagent /bye
For checking that it is working you can use:
$ echo 1234 | gpg -as -
You can also interact directly via stdin with pinentry-touchid, but you need to do the full dance of providing the potions that the gpg-agent usually sends to any pinentry program.
This comment doesn't appear to have any relation to this bug report.
What I meant is that just sending GETPIN
to pinentry-touchid is not enough and it does not considered a valid assuan session, the gpg-agent (and I would expect the same from the program that is trying to use it) should do the valid session.
In this case EOF
is just a report of an early disconnection. That being said it is true that pinentry-mac does not consider this early termination as an unexpected error. I've adjusted the behaviour of the the error check in 82cc231b007b822b4eb11a9d8ba2e773aaae063c and also set the default prompt in case none is passed, which provides a more similar experience to what pinentry-mac does. Can you give it a try?
What I meant is that just sending
GETPIN
to pinentry-touchid is not enough and it does not considered a valid assuan session, the gpg-agent (and I would expect the same from the program that is trying to use it) should do the valid session.In this case
EOF
is just a report of an early disconnection. That being said it is true that pinentry-mac does not consider this early termination as an unexpected error. I've adjusted the behaviour of the the error check in 82cc231 and also set the default prompt in case none is passed, which provides a more similar experience to what pinentry-mac does. Can you give it a try?
Thanks, I'll give it a try soon.
To clarify, the problem (for me at least) is that echo GETPIN | pinentry-touchid
is a perfectly valid way to use a pinentry program, however it returns an error in this case even though a PIN can be fetched from the user. So, the program succeeds in collecting a PIN, but it prints an error message and, more importantly, returns a non-zero exit code.
In my case, I am attempting to use software called passage
which in return uses software called rage
which calls pinentry
to ask for a PIN. I symlinked pinentry to pinentry-touchid
because I want to use it for everything. It fails however. I assume what is happening is that pinentry-touchid
falls back to pinentry-mac
but doesn't return the exit code from the latter. And it also prints that error.
I don't know anything about Assuan commands, but the way that rage
uses pinentry
triggers this error, so I assume that something about pinentry-touchid
is not conforming to spec here. I'll try the fix soon.
Sorry, I don't use go
and don't know how to compile this project, so I can't try your fix.
If you add a Makefile
for dummies, I can make
.
I've added a step to the CI that should build & upload the binaries. You could grab the built binaries from the summary page of the workflow. For instance for the latest commit: https://github.com/jorgelbg/pinentry-touchid/actions/runs/2831484675 (at the bottom).
I had a chance to take a look under the hood at what rage
sends to the pinentry program and I think that pinentry-touchid will keep falling back always to pinentry-mac.
When used with PGP the gpg-agent
sends some identifying metadata about the key that is requesting the passphrase. This metadata is used by pinentry-touchid to tag the passphrase when it is stored in the keychain, since it is possible for a user to have multiple keys. Since this metadata it is not provided at all by rage
pinentry-touchid cannot identify (nor currently store) an item in the keychain and falls back to pinentry-mac for the user to provide a password.
One way to go is to use a default label/name for tagging the keychain item. The downside of this is that you wouldn't be able to have more than 1 keys stored in the keychain (for rage
) because there wouldn't be any way of distinguishing them apart.
Anyhow, this is my interpretation of what I've seen on the interaction between rage
and whatever pinentry program is configured.
Excellent, thanks for that clear explanation. I had wondered how pinentry-touchid knows which secret is being requested. That explains it.
The gpg-agent
must pass an identifier string to the Assuan GETPIN
instruction, or use a different instruction. Is it possible for pinentry-touchid
to support caching of secrets with arbitrary identifiers/tags? Could you give an example of a shell command which does this, like echo GETPIN MY_ID | pinentry-touchid
?
This would not help with rage
specifically, but it would allow other programs to easily use pinentry-touchid
. This may pose an additional security risk, if programs supplied predictable (guessable) identifiers. This could be somewhat reduced by having the pinentry-touchid
program display clearly which program is requesting which secret (process name, tag/identifier requested).
The majority of the information is passed via the SETDESC
command. The pinentry program is expected to extract the metadata from the description. For instance: https://github.com/jorgelbg/pinentry-touchid/blob/1170eb6bc7b23313aee622887b47b77be6e5fb5f/main.go#L52-L53
If the description contains any of the info that matches those regexes (plus the key ID) it will be used to label the keychain item.
If rage
passes down some sort of key id or anything else that could be used to label and retrieve the password, pinentry-touchid should work similarly to how it works with the gpg-agent. This could be also shared via the description that rage
sets when calling the pinentry program.
This would not help with
rage
specifically, but it would allow other programs to easily usepinentry-touchid
. This may pose an additional security risk, if programs supplied predictable (guessable) identifiers. This could be somewhat reduced by having thepinentry-touchid
program display clearly which program is requesting which secret (process name, tag/identifier requested).
The info passed down to pinentry-touchid is essentially provided with the intention of helping the user identify which passphrase is needed (or to automatically fetch it from the keychain) so it shouldn't be insecure by default. In the gpg-agent case, the private key is never shared. In any case, is responsibility of the caller that sends the commands to pinentry.
Having said that, I'm not familiar enough with age
/rage
to say which info could potentially be shared with pinentry-touchid 😅.
Describe the bug
When running
echo "GETPIN" | pinentry-touchid
I get the following responsepinentry-mac runs as expected - I have tried to unsinstall & re-install pinentry-mac & pinentry-touchid with no sucess at this point. I have also been looking for similar issues but haven't found a solution as of yet.
System information
macOS
GPG
gpg --version
Yes.
Configuration
gpgconf
.Logs
gpg-agent
:pinentry-touchid
: