5

I'm trying to understand Yubico's documentation of the U2F standard, and getting hung up on the PIV attestation piece.

The security claim appears to be that the authoritatively-signed attestation certificate sent by the device upon registration will allow the relying party (~= server) to verify that the keying material produced by the U2F registration has not been stored or copied outside of the device.

I'm confused about how this can be possible. How does the attestation certificate represent the association between the public and private key material? How can the attestation certificate be signed for every keypair generated on the fly?

The only code that I can find showing how the attestation certificates are generated is the (static, self-signed) certificate used by this SoftU2F implementation in Rust: https://github.com/danstiner/rust-u2f/blob/master/u2f-core/src/self_signed_attestation.rs

There must be something I'm missing here, probably in how Yubikey specifically signs the attestation certificates, perhaps taking advantage of the fact that the keying material for every registration is in some way.

Can anyone help me understand how, for example, the attestation certificates produced by Yubikey's U2F devices and signed by this CA cert would allow a server to verify the provenance of the keying material used in the U2F registration, or the authenticity of the device model information?

Put another way: If I register a U2F device and receive its attestation certificate, key handle, and public key (as described in the protocol details), and I trust the root CA of the attestation cert... how can I use this to verify the provenance of the keying material?

Dan Lenski
  • 313
  • 2
  • 7
  • Based on [this useful answer](https://security.stackexchange.com/a/109491/95855), it appears that the attestation certificate is supposed to "sign the public key" produced in the registration exchange. I remain confused about the _mechanics_ of how this works, or how it's expressed in the U2F output, however. – Dan Lenski Jan 24 '20 at 01:42
  • 1
    PIV attestation appears to be a separate feature of some Yubikeys unrelated to their U2F capability. Your second link is for the U2F attestation, and that page includes a link to Yubico's U2F Root CA. – AndrolGenhald Jan 25 '20 at 03:49

1 Answers1

3

The U2F spec overview says:

The intention is that the public keys of all the 'Attestation' key pairs used by each vendor will be available in the public domain - this could be implemented by certificates chaining to a root public key or literally as a list. We will work within FIDO to decide the details on how certified vendors can publish their attestation public keys.

In practice most key vendors provide a root certificate somewhere that you can use to verify the attestation certificate. This works just like any other PKI.


Each authenticor contains an attestation private key that is used to create attestation signatures, and the associated attestation certificate that is sent as part of each registration the authenticator is used for. The attestation private key will be shared by at least 100,000 authenticators to prevent services from identifying an individual based on the attestation key. The purpose is to provide a way to prove which vendor manufactured the key, as the private key should be impossible to extract from the authenticator, and is thus known only to the vendor.

The registration response message includes an attestation certificate and a signature. The attestation certificate is a normal DER encoded X.509 certificate, and the signature is created with the attestation private key over the rest of the response message and part of the associated request.

Registration Response Message from FIDO U2F V1.2 Spec

To properly verify the attestation, first the attestation public key is extracted from the certificate and used to verify the signature of the response. Without this step, an attacker could simply take the attestation certificate from a known to be accepted authenticator and use it instead of their own device's attestation certificate.

After the response signature has been verified (tying the attestation certificate to the registration keypair), the attestation certificate itself must be verified. As an example, here is the certificate from one of my keys, decoded with the openssl x509 CLI:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 618376000 (0x24dbab40)
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN = Yubico U2F Root CA Serial 457200631
        Validity
            Not Before: Aug  1 00:00:00 2014 GMT
            Not After : Sep  4 00:00:00 2050 GMT
        Subject: CN = Yubico U2F EE Serial 13503277888
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:02:b0:94:be:34:7d:47:79:41:c4:77:8e:be:c5:
                    ca:4d:ed:2a:47:9f:aa:1e:6f:ec:39:af:eb:de:0c:
                    20:70:cb:5b:d4:bd:69:c9:6a:78:e3:bf:87:51:fe:
                    b5:79:1b:8d:fa:ca:c2:94:01:75:1c:b1:57:b9:7c:
                    09:e4:39:1a:36
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            1.3.6.1.4.1.41482.1.1: 

    Signature Algorithm: sha256WithRSAEncryption
         a3:63:ae:0e:98:3a:f3:0b:ba:f1:2c:8b:2d:f3:5a:59:bf:1c:
         bb:4a:1b:0f:cb:68:c4:84:55:84:90:f6:87:34:58:65:b8:db:
         02:69:c3:46:e5:53:88:4c:2c:56:07:af:0e:a2:7b:90:ac:8c:
         f1:ef:43:1f:72:ac:18:9d:b2:1c:82:49:14:bf:17:88:a5:51:
         1a:33:d0:7b:4c:8e:34:64:7c:e9:f6:1e:15:16:a9:a9:b3:6e:
         90:0a:40:20:61:f6:9a:a4:6e:12:c5:32:b9:93:f9:42:3e:fa:
         aa:4c:f9:a3:b6:54:b4:dd:de:f2:92:4a:54:8f:d5:99:95:51:
         0d:d4:f7:f4:d9:a4:d5:21:93:87:3c:71:c9:b8:7e:86:85:3e:
         9e:2d:a7:5e:8f:0c:6d:28:30:53:74:d4:ef:dd:5e:14:96:f8:
         c3:39:06:10:7b:d6:8b:d6:35:0d:aa:d2:c3:78:11:ec:a3:ca:
         43:bc:93:0b:73:40:97:de:f6:9d:68:8d:94:55:0c:4c:fb:18:
         a9:e2:4b:86:a2:e5:d8:8f:49:98:99:a0:9b:ce:5b:81:0c:53:
         6c:af:39:0d:c8:bd:de:96:0d:f3:30:ca:ca:bc:05:21:a1:83:
         23:95:7f:fe:bc:a5:9c:a9:0b:20:b1:0d:09:b5:23:1c:58:c2:
         7e:ba:67:83

The issuing certificate can be determined from the Issuer field, in this case it's Yubico's U2F Root CA. Assuming the application trusts that CA, it would take the public key from that root certificate (the root certificate itself would come from a list of trusted roots) and use it to verify the signature on the attestation certificate. If the verification is successful, the registration keypair will be cryptographically tied to the attestation certificate, and the attestation certificate will be cryptographically tied to the trusted root.

If you trust that the vendor has manufactured their authenticators properly so that the attestation private key and the key wrapping secret (or key storage depending on design) cannot be extracted, then you can be confident that the registered key is from an authenticator created by the vendor you obtained the root certificate from.

AndrolGenhald
  • 15,436
  • 5
  • 45
  • 50
  • Aha, thank you. This clears it up nicely. The part that I was missing is that every device contains _not only_ an individualized key wrapping secret, but _also_ an attestation private key (the latter shared by batches of 100k+ keys). – Dan Lenski Jan 25 '20 at 18:22