Skip to content

[Bug]: kms/yubikey silently tries the factory default PIN and burns PIV PIN retries #1074

Description

@TicketWindowSeat

Steps to Reproduce

On a YubiKey whose PIV PIN has been changed from the factory default (use a disposable key — this consumes real PIN retries):

step kms sign --kms "yubikey:" "yubikey:slot-id=9c" --in file
# or any CreateSigner+Sign through go.step.sm/crypto/kms/yubikey with no pin in the URI

Each run decrements the card's PIN retry counter (ykman piv info shows it) until the PIN is blocked. Three runs of the same innocent command block the PIN; recovery needs the PUK, and a fumbled PUK forces a PIV reset that destroys the PIV keys.

Your Environment

  • OS - Windows 11 (also reproduced on 32-bit Linux/pcsc-lite)
  • Version - go.step.sm/crypto master (kms/yubikey/yubikey.go:202, pin := "123456"), piv-go v2.6.0; observed via step CLI 0.30.6 / step-kms-plugin 0.17.0; YubiKey 4 fw 4.3.3, slot 9c, PIN policy ALWAYS

Expected Behavior

A failed verification that says where the PIN came from and how to provide the right one, e.g.

verify pin: smart card error 63c2: verification failed (2 retries remaining); the YubiKey factory default PIN was tried because no PIN was available; provide one with pin-value, pin-source or pin-prompt

(or the operation refusing to guess at all). The fallback itself is documented in New's godoc, so keeping it and making the failure self-diagnosing before the last retry is gone preserves behavior.

Actual Behavior

When a yubikey: URI carries no PIN, kms/yubikey.New silently falls back to the YubiKey factory default PIN 123456. CreateSigner/CreateDecrypter then pass that guessed PIN with piv.PINPolicyAlways, so every sign or decrypt sends a VERIFY with a PIN the user never chose. If the card's PIN is not the default, each operation consumes one of the card's 3 PIN retries and fails with:

verify pin: smart card error 63c2: verification failed (2 retries remaining)

Nothing in the error says the library picked the PIN itself, so it reads as "your PIN is wrong" to a user who never typed one.

Additional Context

in smallstep/cli#1492 a user following the official mTLS YubiKey tutorial had a correct pin-value that didn't propagate to the step-kms-plugin sign subprocess — the fallback burned all three retries and the YubiKey's PIV application had to be reset (maintainer-confirmed). step-kms-plugin#83 shows the same opaque error confusing another user with a non-default PIN.

Contributing

Vote on this issue by adding a 👍 reaction.
To contribute a fix for this issue, leave a comment (and link to your pull request, if you've opened one already).

I have a minimal patch ready (error-message wrap only, no behavior change, hardware-free tests; verified against a real YubiKey 4 with a non-default PIN) and will open a PR referencing this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions