@remy I’ve made some progress, and it’s some kind of a key signature disagreement. If I dig into the healthcheck and print out the exception that occurs inside gpgCanDecryptVerify(), I get the following error:
Cake\Core\Exception\CakeException: Decryption failed. Invalid signature. Expected 9C213977C9C44FBAA4E7BD7B8DCCC57DF1FF2B3F and got 9BD78B0132367C3BD73E150E47EB65A148F5433E. in /usr/local/www/passbolt/src/Utility/OpenPGP/Backends/Gnupg.php:602
The key fingerprint in config/passbolt.php matches the expected value above, and also matches what I get from gpg:
$ gpg --list-secret-keys --keyid-format long
gpg: Warning: using insecure memory!
/home/www/.gnupg/pubring.kbx
----------------------------
sec rsa2048/8DCCC57DF1FF2B3F 2022-01-05 [SCEA]
9C213977C9C44FBAA4E7BD7B8DCCC57DF1FF2B3F
uid [ultimate] ...
ssb rsa2048/47EB65A148F5433E 2022-01-05 [SEA]
And, if I extract the encrypted message produced by gpgCanDecryptVerify() and try to decrypt it manually, I see that the message was signed by the subkey, which reportedly has the fingerprint that healthcheck is getting back.
$ gpg2 --decrypt message
gpg: Warning: using insecure memory!
gpg: encrypted with rsa2048 key, ID 47EB65A148F5433E, created 2022-01-05
"..."
test messagegpg: Signature made Thu Jan 6 11:19:13 2022 PST
gpg: using RSA key 9BD78B0132367C3BD73E150E47EB65A148F5433E
gpg: Good signature from "..." [ultimate]
If I set the subkey fingerprint in config/passbolt.php instead of the main key fingerprint, healthcheck complains about a mismatched key but the decryption and verify steps pass.
GPG Configuration
[PASS] PHP GPG Module is installed and loaded.
[PASS] The environment variable GNUPGHOME is set to /home/www/.gnupg.
[PASS] The directory /home/www/.gnupg containing the keyring is writable by the webserver user.
[PASS] The server OpenPGP key is not the default one
[PASS] The public key file is defined in config/passbolt.php and readable.
[PASS] The private key file is defined in config/passbolt.php and readable.
[FAIL] The server key fingerprint doesn't match the one defined in config/passbolt.php.
[HELP] Double check the key fingerprint, example:
[HELP] sudo su -s /bin/bash -c "gpg --list-keys --fingerprint --home /home/www/.gnupg" www | grep -i -B 2 'SERVER_KEY_EMAIL'
[HELP] SERVER_KEY_EMAIL: The email you used when you generated the server key.
[HELP] See. https://www.passbolt.com/help/tech/install#toc_gpg
[PASS] The server public key defined in the config/passbolt.php (or environment variables) is in the keyring.
[PASS] There is a valid email id defined for the server key.
[PASS] The public key can be used to encrypt a message.
[PASS] The private key can be used to sign a message.
[PASS] The public and private keys can be used to encrypt and sign a message.
[PASS] The private key can be used to decrypt a message.
[PASS] The private key can be used to decrypt and verify a message.
[PASS] The public key can be used to verify a signature.
However, I still get a 500 error when trying to log in after this change. I captured the network traffic and the client successfully GETs from /users/csrf-token.json, but receives a 500 back when POST’ing GPG data to /auth/login.json. The 500 error is generated by AuthLoginController.php, which I guess still can’t decrypt and/or verify the client response.
This key vs subkey discrepancy, maybe it’s a library version issue?