This is the story on how I discovered that Yubico used an invalid certificate chain in their
Personal Identity Verification (PIV) attestation feature on YubiKey 4.3
and YubiKey NEO, which could
only be solved by a new hardware release. The impact for users and organizations is that the
certificate chain will be deemed invalid by tools that verifies the chain properly, such as OpenSSL
version 1.1.0 and later. Yubico has published a custom Python script that can be used to verify
their attestation certificate chains. Organizations can also deploy their own certificates onto the
affected YubiKeys instead of relying on Yubico’s public key infrastructure (PKI).
UPDATE 2020-JAN-08: I’ve striked out YubiKey NEO above since that device never had the
attestation capability. YubiKey NEO was erroneously mentioned in Yubico’s support article about
which has now been corrected. Thanks to Klas Lindfors at Yubico for pointing out this in my
yubico-piv-tool pull request #216.
What Is A YubiKey?
A YubiKey is a small device you use over USB or NFC with your computer or mobile phone. It can store
and protect different kinds of secrets used for OATH (TOTP, HOTP), U2F, WebAuthn and asymmetric
encryption like PGP etcetera. You can either import existing keys you have generated on your
computer or have the YubiKey generate them on board. The main advantage for that is that the private
key cannot be extracted from the device. That means that physical access to one particular YubiKey
is needed in order to sign something with the private key or decrypt anything encrypted with the
What Is Key Attestation?
Organizations might want to buy YubiKeys for their employees for use with GPG, SSH etcetera and
require that only asymmetric keys generated on the devices are used in their environment. In order
to prevent mistakes or “lazy” employees who want to cut corners they might want to require proof
that a key pair was actually generated on a YubiKey and not just generated on a laptop and stored
YubiKey 4.3 and later come with a feature called key attestation which means that the YubiKey comes
with a private key that can be used to produce a certificate that a particular key pair was actually
generated on board on the device.
If you want to read Yubico’s own explanation, see PIV
Attestation and Using
Attestation for technical details
on how to do it.
The Discovered Certificate Problem
I found that the attest certificate, the intermediate attestation certificate and Yubico’s PIV root
CA didn’t form a proper verifiable certificate chain following Yubico’s documented example. First I
thought there was a problem with the
openssl commands and the contents of individual
and contacted Yubico support via email (see below for full email conversation). Soon I discovered
that the OpenSSL version mattered and started dissecting the OpenSSL source
code and found that it was actually an improvement in the
verification code that made the YubiKey certificate to not verify.
I found that the attestation certificate embedded from factory on my YubiKey (with subject CN =
Yubico PIV Attestation) had neither the required Basic Constraint
CA:TRUE nor the Key Usage
Certificate Sign so it wasn’t trusted to issue any certificates but it did so anyway.
My conclusion is that Yubico used only old versions of OpenSSL to test the attestation feature and
thought the certificate chain was properly constructed since OpenSSL didn’t complain.
Maximum Path Length
After or at least outside of my conversation with the Yubico support I realized that there was a
problem with their PIV root CA as well. It was marked as a CA, but
pathlen was set to 0:
X509v3 Subject Key Identifier:
X509v3 Basic Constraints:
X509v3 Key Usage: critical
Certificate Sign, CRL Sign
From the Basic Constraints section of RFC 5280, Internet X.509 Public Key Infrastructure
Certificate and Certificate Revocation List (CRL)
Profile (my emphasis):
The pathLenConstraint field is meaningful only if the cA boolean is
asserted and the key usage extension, if present, asserts the
keyCertSign bit (Section 188.8.131.52). In this case, it gives the
maximum number of non-self-issued intermediate certificates that may
follow this certificate in a valid certification path. (Note: The
last certificate in the certification path is not an intermediate
certificate, and is not included in this limit. Usually, the last
certificate is an end entity certificate, but it can be a CA
certificate.) A pathLenConstraint of zero indicates that no non-self-issued
intermediate CA certificates may follow in a valid
certification path. Where it appears, the pathLenConstraint field
MUST be greater than or equal to zero. Where pathLenConstraint does
not appear, no limit is imposed.
So their attestation intermediate certificate is not allowed to sign any end-entity certificates,
which it actually is used for.
The 23rd of September 2018 Yubico announced YubiKey 5: Introducing the YubiKey 5 Series with New
NFC and FIDO2 Passwordless
On the same day they published information about the problem I found and a workaround for old
devices in their support article PIV Attestation Verification Fails with OpenSSL
and updated their PIV attestation
introduction with a link to a
new root CA (.pem,
my copy, text
format) and a note about the old root
my copy, text
It seems Yubico also found out about the problem with the path length. The only difference in the
new root CA (apart from the obvious different signature) is that the
pathlen field changed:
< CA:TRUE, pathlen:0
> CA:TRUE, pathlen:1
That’s a bit unconventional. They chose to keep the same serial number on the new certificate even
though the fingerprint changed.
Issuer: CN = Yubico PIV Root CA Serial 263751
Subject: CN = Yubico PIV Root CA Serial 263751
The intermediate certificate stored on the YubiKey 5 has a new key pair but also the following added
property which allows it to sign certificates:
> X509v3 Basic Constraints: critical
> CA:TRUE, pathlen:0
Workaround: Using Yubico’s Verification Python Script
In the announcement linked to above about the OpenSSL 1.1.0 problems Yubico included an interactive
customers can use instead of OpenSSL to verify the certificate chain of an attestation produced on a
Workaround: Using Your Own CA
If you own an affected YubiKey 4.3 and want to use the attestation feature but don’t want to buy a
YubiKey 5 you can instead use your own PKI. By using the
import a key and a certificate to the special attestation key slot
f9. By doing so you’re not
affected by the problem since you will replace the factory attestation key and certificate your
YubiKey came with.
Email Conversation With Yubico Support
For transparency, see the full email conversation I had
with the Yubico support regarding attestation problems.
Do you have comments? Interact with this tweet:
Thanks to Alexander Kjäll for reviewing.
Broken chain image from Clipart