hashicorp / terraform-provider-aws

The AWS Provider enables Terraform to manage AWS resources.
https://registry.terraform.io/providers/hashicorp/aws
Mozilla Public License 2.0
9.8k stars 9.15k forks source link

aws_iam_access_key and aws_iam_user_login_profile pgp_key vs elliptic curves #25683

Closed lucasvuotto closed 2 months ago

lucasvuotto commented 2 years ago

Community Note

Terraform CLI and Terraform AWS Provider Version

$ terraform -v
Terraform v1.2.4
on linux_amd64
$ terraform providers

Providers required by configuration:
.
└── provider[registry.terraform.io/hashicorp/aws] ~> 4.21.0

Providers required by state:

    provider[registry.terraform.io/hashicorp/aws]

Affected Resource(s)

At least

and based on a quick GitHub's code search, aws_lightsail_key_pair is probably affected too.

Terraform Configuration Files

It's a reproducer script, as the setup requires PGP keys. Alternatively, I can provide a tarball with the directory the script generates.

#!/bin/sh

for p in terraform gpg base64; do
    if ! command -v "$p" >/dev/null; then
        echo "required program $p not found" >&2
        exit 1
    fi
done

wd=repro
mkdir "$wd"

cd "$wd"
mkdir -m 700 gnupg
GNUPGHOME=$(pwd)/gnupg
export GNUPGHOME

# create keys
for keytype in ed25519 nistp256 nistp384 nistp521; do
    gpg --batch \
        --pinentry-mode loopback --passphrase "" \
        --quick-gen-key "uid-$keytype" "$keytype" default 0
    fpr=$(gpg -k --with-colons "uid-$keytype" |
        grep ^fpr: |
        cut -d : -f 10)
    if [ "$keytype" = ed25519 ]; then
        subkeytype=cv25519
    else
        subkeytype=$keytype
    fi
    gpg --batch \
        --pinentry-mode loopback --passphrase "" \
        --quick-add-key "$fpr" "$subkeytype" encr 0
    gpg --export "$fpr" | base64 >"$keytype.asc"
done

# create Terraform file
cat - >main.tf <<'EOF'
terraform {
  required_version = "~> 1.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.21.0"
    }
  }
}

provider "aws" {
  region = "us-east-1"
}

locals {
  keytypes = toset([
    "ed25519",
    "nistp256",
    "nistp384",
    "nistp521",
  ])
}

resource "aws_iam_user" "users" {
  for_each = local.keytypes
  name     = "test-user-${each.value}"
}

resource "aws_iam_user_login_profile" "login_profile" {
  for_each  = local.keytypes
  user      = aws_iam_user.users[each.value].name
  pgp_key   = file("${each.value}.asc")
}

EOF
for keytype in ed25519 nistp256 nistp384 nistp521; do
    cat - >>main.tf <<EOF
output "password_$keytype" {
  value = aws_iam_user_login_profile.login_profile["$keytype"].encrypted_password
}
EOF
EOF
done

terraform init && terraform apply

for keytype in ed25519 nistp256 nistp384 nistp521; do
    terraform output -raw "password_$keytype" |
        base64 -d | gpg -d
done

cat - >&2 <<EOF

###############################################################################

To cleanup, run

    cd "$wd"
    terraform apply -destroy
    cd ..
    rm -fr -- "$wd"

EOF

Debug Output

Panic Output

Expected Behavior

Being able to decrypt the encrypted payload.

Actual Behavior

When encrypting against an EC, despite the PGP packet being seemingly well-formed (based on the fact that it contains the keytype and fingerprint), the payload can't be decrypted:

gpg: encrypted with 256-bit ECDH key, ID 682BE5A7214CB970, created 2022-07-05
      "uid-ed25519"
gpg: public key decryption failed: Wrong secret key used
gpg: decryption failed: No secret key
gpg: encrypted with 256-bit ECDH key, ID 2AD2EFC06107AFE5, created 2022-07-05
      "uid-nistp256"
gpg: public key decryption failed: Wrong secret key used
gpg: decryption failed: No secret key
gpg: encrypted with 384-bit ECDH key, ID 772DFE25EDE92AEF, created 2022-07-05
      "uid-nistp384"
gpg: public key decryption failed: Wrong secret key used
gpg: decryption failed: No secret key
gpg: encrypted with 521-bit ECDH key, ID 18AEBFDC8BB9FA3B, created 2022-07-05
      "uid-nistp521"
gpg: public key decryption failed: Wrong secret key used
gpg: decryption failed: No secret key

Steps to Reproduce

Run the inlined script. It requires terraform, gpg and base64. It will:

  1. create a repro/ directory which will be the workplace
  2. create an empty, temporary GNUPGHOME
  3. create Ed25519, NIST P-256, NIST P-384 and NIST P-521 keys.
  4. create a main.tf with the required configuration and resources. In particular, do note that it includes aws_iam_user resources.
  5. run terraform init && terraform apply
  6. attempt to decrypt the encrypted password
  7. print instructions on how to cleanup the repro/ directory

Important Factoids

Didn't try against keychain as I don't have an account there.

References

Didn't find any.

lucasvuotto commented 2 years ago

Got some time to try out more stuff:

lucasvuotto commented 2 years ago

Managed to try out some more stuff: the culprit is the version: both 2.2.19 and 2.2.20 fail, and 2.2.21 succees: https://dev.gnupg.org/T4897 . From there, the important bit of information is

which is exactly what I'm experiencing. Might it be worth a comment in the documentation?

github-actions[bot] commented 3 months ago

Marking this issue as stale due to inactivity. This helps our maintainers find and focus on the active issues. If this issue receives no comments in the next 30 days it will automatically be closed. Maintainers can also remove the stale label.

If this issue was automatically closed and you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thank you!

github-actions[bot] commented 1 month ago

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.