1

I want to use gpg from another user (user2), so that the primary user (user1) does not have access to the encrypted file, but only to the part the script will output.

Added a sudo rule for user1 to run /bin/gpg as user2. When I try to execute user1@host: sudo -u user2 gpg /home/user2/pass.gpg an error gpg: decryption failed: No secret key appears (symmetric encryption).

I add the --pinentry-mode loopback parameter, the password is requested directly in the console (without any "Enter password" or input field, just on a new line) and decryption takes place.

From what I've read, using the pinentry-mode loopback option reduces security because the password is transferred without using gpg-agent, but directly with gpg. Did I get it right or is this parameter safe to use? Or is there another way to achieve your goal?

2
  • 2
    Instead of playing with fake user, you could play with GNUPGHOME=$HOME/.alternate-gnupg gpg ... to store other pseudo user profile under your private permissions. Commented Jan 23, 2022 at 8:04
  • @F.Hauri I'm sorry, but I don't quite get it. There is a file.gpg that should not be readable from user1. If I specify .alternate-gnupg from under user2, there is a error with agent gpg when I try to decrypt it. And if I decrypt from user1 I have no permissions for file.gpg. Commented Jan 23, 2022 at 14:52

1 Answer 1

2

Avoiding loopback is possible by simply fixing the choice of pinentry and the tty permissions:

# Once:
pkcon install pinentry-curses # or via apt, yum, pacman, etc.
sudo -u user2 bash -c 'echo pinentry-program /bin/pinentry-curses > /home/user2/.gnupg/gpg-agent.conf'
sudo -u user2 killall gpg-agent
# Your fixed script is:
sudo -u user2 script /dev/null -c 'gpg pass.gpg'
# No need for --pinentry-mode loopback

My default pinentry was pinentry-gnome3, which like all GUI apps, works poorly over sudo. Sudo makes $(tty) owned by root:tty and inaccessible by the pinentry which reopens it. script /dev/null launches a passthrough sub-PTY properly owned by user2:tty. This weaker ownership makes no difference as it matches my login /dev/ttyN. For better security with the new command, use a wrapper script in sudo.

I'm on GnuPG 2.4.8. The message public key description failed: No secret key shouldn't appear when using symmetric encryption. I only get that message with asymmetric encryption after sudo -u user2 bash -c 'echo 123 > pass; gpg --full-generate-key; gpg -e -r MyGPGUserID pass; mv ~/.gnupg/private-keys-v1.d{,.bak}'; sudo -u user2 script /dev/null gpg pass.gpg. Check sudo -u user2 gpg --list-secret-keys and ensure the corresponding public key is referenced by -r and present in the sending user's gpg --list-keys.

The real error message for symmetric encryption that I tackled was problem with the agent: No pinentry. Without my solution, it is elicited by echo 123 > pass; gpg -c pass; sudo -u user2 gpg pass.gpg. With actual symmetric encryption, pinentry-mode loopback doesn't seem to impact security at all. The gpg-agent and its pinentry are for protecting private keys for asymmetric encryption in gpg-agent, while symmetric keys should be rotated frequently. The protection is presumably mostly against vulnerabilities in the GUI pinentry and to a less extent, vulnerabilities in /bin/gpg. As evidenced by the CPU usage, the gpg process does the decryption so the symmetric key is sent to it anyway in both symmetric and asymmetric cases. Only with asymmetric encryption there's a separate key protectable by gpg-agent.

It's counterintuitive to specify that "primary user (user1) does not have access to the encrypted file", as a secure system should be able to safely make the ciphertext (encrypted file) public. The "part [your] script will output" will be at /home/user2/pass not stdout, and I hope user1 has a way to "have access to" it. With the plaintext and the key, user1 would only need the random IV to recreate the ciphertext. That capability affects nobody but rare blockchains storing ./pass.gpg off-chain and using the IV to allow repudiation between the on-chain hash and ./pass.

I have a more comprehensive pinentry setup using systemd sockets to protect private-keys-v1.d for asymmetric encryption as that's more people's goal. It has both GUI and tty pinentry, and its goal is handling Git's GPG signing and SSH. A minor feature is it also working with your 100% unmodified sudo -u user2 gpg /home/user2/pass.gpg command, when my "home-gpg" is changed to user2 and "home" to user1. However, it's not peer-reviewed and I'm using it mainly because Ubuntu can't use SELinux (that answer doesn't work for this question) such as to restrict private-keys-v1.d to gpg-agent, which should be enough assuming ptrace_scope=1.

In comparison:

  • For symmetric encryption:
    • Just share pass.gpg to user1, with no real loss in security
    • If company policy mandates, use your sudo command with --pinentry-mode loopback
  • For asymmetric encryption:
    • --pinentry-mode loopback isn't that bad for non-GUI input running as user2
    • Fixing the pinentry using script is slightly better as it uses more-tested code paths and file permissions
    • The SELinux answer to another question doesn't answer this one, but is what more people want to use
    • My systemd solution on GitHub is for when your distro doesn't have SELinux
0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.