The default behavior of Crostini’s Debian Stretch container is to use a curses-based pinentry. This behaves strangely, in two different ways:
- 
Inherently, it shows the semi-graphical pinentry dialog in the terminal that has last called gpg-connect-agent updatestartuptty /bye. You can do this in.bashrcor similar, but if your habit is (like mine) to run many different terminals at once, you would need to call this whenever focus changes — otherwise the pinentry dialog will invariably come up in a random terminal. Of course this might still be inconvenient if pinentry is triggered from a UI application instead of on the console.
- 
If the pinentry dialog comes up in a terminal other than the one where the gpg process originated, it doesn’t work correctly anyway — the dialog is drawn on screen, but the command prompt (or whatever is running) remains active in the background and grabs input. I didn’t investigate this any further. 
As far as I’m aware, there is no way of making this work other than somehow executing gpg-connect-agent updatestartuptty /bye every time a terminal window is focused. I didn’t want to go down that path and I was wondering why a graphical UI pinentry wasn’t used by default. But of course the standard container is just a very basic starting point and especially doesn’t come with loads of UI stuff installed.
Some wasted time…
The first UI pinentry I tried was pinentry-gnome3, and I immediately stumbled upon the next issue: when started from the command line, the error No $DBUS_SESSION_BUS_ADDRESS found, falling back to curses was shown. I have never had reason to look into the exact details of how dbus-daemon is started on Debian, and I suspect that the launch process is somehow out of whack on Crostini due to the fact that no conventional X session is started. I found that dbus-daemon was running, but the environment wasn’t configured correctly. As a workaround I configured terminator to start through dbus-run-session. I created /usr/local/bin/dbus-terminator:
#!/bin/sh
/usr/bin/dbus-run-session -- /usr/bin/terminator
Then I copied /usr/share/applications/terminator.desktop to /usr/local/share/applications and modified it to use a different name (DBUS-Terminator) and call dbus-terminator. This approach means that the entry appears in the Chromebook launcher automatically, and it configures DBUS_SESSION_BUS_ADDRESS correctly for the terminator session.
This made pinentry-gnome3 quite happy and it stopped showing the error message. However, it still wouldn’t work! I did notice at this point that gpg-agent was ignoring pinentry-program in ~/.gnupg/gpg-agent.conf — it always ran pinentry regardless of the entry there — but pinentry is just a configured alternative anyway, so I can update-alternatives --config pinentry to explicitly activate pinentry-gnome3. In spite of all that, it would always fall back to curses — no idea why, I stopped investigating at this point because I wasn’t fixed on the Gnome version of pinentry. I summarized all of the above in the hopes that somebody else may benefit from it!
Then what?
Now for an actual working solution: pinentry-qt. It turns out that this is a much easier choice. Once installed and activated through update-alternatives, it runs correctly without further trouble. I ended up thinking, if only I’d been able to find a simple solution when I searched, one that really works in Crostini… so I wrote this, hope it helps!