GPG can decrypt, cannot verify

@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?