PGP signature verification fails with gopenpgp v3: "no valid self signature found"
# PGP signature verification fails with gopenpgp v3: "no valid self signature found"
## Description
tfswitch v1.4.5 through v1.15.0 (latest) fails to verify HashiCorp's PGP signature when downloading any Terraform version. The error is:
```
Could not verify PGP signature: Signature Verification Error: Invalid signature caused by no valid self signature found
```
This is a regression introduced when tfswitch migrated from `gopenpgp/v2` to `gopenpgp/v3` (PR #579).
## Root Cause
HashiCorp's PGP key (`C874011F0AB405110D02105534365D9472D7468F`) contains an **expired signing subkey** alongside a valid one:
```
pub rsa4096 2021-04-19 [SC] [expires: 2030-03-01]
C874011F0AB405110D02105534365D9472D7468F
uid HashiCorp Security (hashicorp.com/security) <security@hashicorp.com>
sub rsa4096 2021-04-19 [E] [expires: 2030-03-01]
sub rsa4096 2021-04-19 [S] [expired: 2022-04-20] ← EXPIRED signing subkey
sub rsa4096 2021-04-21 [S] [expires: 2030-03-01] ← Valid signing subkey
```
`gopenpgp/v2` (used in v1.4.4 and earlier) handles this correctly — it finds the valid signing subkey and verifies successfully. `gopenpgp/v3` (used in v1.4.5+) fails with "no valid self signature found" when it encounters the expired subkey, instead of falling through to the valid one.
The PGP key itself is correct (7717 bytes, downloaded from `https://www.hashicorp.com/.well-known/pgp-key.txt`). Standard GPG verifies the signature successfully:
```
$ gpg --import /tmp/hc_pgp.txt
gpg: key 34365D9472D7468F: public key "HashiCorp Security (hashicorp.com/security) <security@hashicorp.com>" imported
$ gpg --verify terraform_1.6.6_SHA256SUMS.72D7468F.sig terraform_1.6.6_SHA256SUMS
gpg: Signature made Wed Dec 13 13:14:24 2023 EST
gpg: using RSA key 374EC75B485913604A831CC7C820C6D5CD27AB87
gpg: Good signature from "HashiCorp Security (hashicorp.com/security) <security@hashicorp.com>"
Primary key fingerprint: C874 011F 0AB4 0511 0D02 1055 3436 5D94 72D7 468F
Subkey fingerprint: 374E C75B 4859 1360 4A83 1CC7 C820 C6D5 CD27 AB87
```
GPG correctly selects the valid signing subkey (`CD27AB87`, expires 2030) and verifies the signature. This confirms the signature and key are both valid — the bug is in gopenpgp v3's handling of keys with expired subkeys.
## Reproduction
Tested on macOS (darwin/arm64) and Linux (linux/amd64) with identical results.
```bash
# Download tfswitch v1.15.0
curl -sL "https://github.com/warrensbox/terraform-switcher/releases/download/v1.15.0/terraform-switcher_v1.15.0_darwin_arm64.tar.gz" -o /tmp/tfswitch_v1.15.0.tar.gz
tar xzf /tmp/tfswitch_v1.15.0.tar.gz -C /tmp/
# Create a minimal test module
mkdir -p /tmp/tfswitch_repro
cat > /tmp/tfswitch_repro/versions.tf << 'EOF'
terraform {
required_version = "~> 1.6.0"
}
EOF
# Run with clean cache — FAILS
cd /tmp/tfswitch_repro
TF_INSTALL_PATH=/tmp/tfswitch_repro/.versions /tmp/tfswitch -g TRACE
# => FATAL Error downloading: Signature of checksum file could not be verified
```
### Comparison with v1.4.4 (last version using gopenpgp/v2) — SUCCEEDS
```bash
curl -sL "https://github.com/warrensbox/terraform-switcher/releases/download/v1.4.4/terraform-switcher_v1.4.4_darwin_arm64.tar.gz" -o /tmp/tfswitch_v1.4.4.tar.gz
tar xzf /tmp/tfswitch_v1.4.4.tar.gz -C /tmp/ -s '/tfswitch/tfswitch144/'
rm -rf /tmp/tfswitch_repro/.versions
cd /tmp/tfswitch_repro
TF_INSTALL_PATH=/tmp/tfswitch_repro/.versions /tmp/tfswitch144 -g TRACE
# => Checksum file signature verification successful
# => Switched Terraform to version "1.6.6"
```
### Terraform version is irrelevant
Tested with both `~> 1.6.0` (resolves to 1.6.6) and `~> 1.9.0` (resolves to 1.9.8) — identical failure. The bug is in how gopenpgp v3 parses HashiCorp's PGP key itself, not in any specific Terraform release's signature files. Every Terraform version uses the same PGP key (`72D7468F`) for signature verification.
## Version Boundary
| Version | gopenpgp | Result |
|---------|----------|--------|
| v1.4.4 | v2.8.3 | ✅ PASS |
| v1.4.5 | v3.2.1 | ❌ FAIL |
| v1.15.0 | v3.3.0 | ❌ FAIL |
## Impact
**All tfswitch v1.4.5+ users are affected** when downloading any Terraform version with a clean cache (no pre-existing binary). This blocks all CI/CD pipelines using tfswitch, since they typically start with an empty cache on each run.
## Workaround
Pin tfswitch to v1.4.4 (last working version):
```bash
curl -L https://github.com/warrensbox/terraform-switcher/releases/download/v1.4.4/terraform-switcher_v1.4.4_linux_amd64.tar.gz | tar xz -C /usr/local/bin/
```
## Environment
- tfswitch: v1.4.5 through v1.15.0
- OS: darwin/arm64 and linux/amd64
- HashiCorp PGP key: 7717 bytes, fingerprint C874011F0AB405110D02105534365D9472D7468F
- Key source: https://www.hashicorp.com/.well-known/pgp-key.txt (verified identical to https://keybase.io/hashicorp/pgp_keys.asc)
关闭于 2026-03-13 20 条评论