YubiKey Authentication With pam_u2f.so
YubiKey and U2F
A YubiKey is a
small hardware authentication device
that plugs into a USB port.
Several models
are available, for US$ 20–70.
The FIDO protocol verifies that the user
has access to the private key corresponding to the public
key registered with the system.
YubiKey devices can run FIDO using an elliptic curve
key pair installed at the factory.
The
PAM mechanism on Linux
supports the pam_u2f.so
library module.
You can specify authentication using
U2F or Universal 2nd Factor
devices communicating with FIDO.
YubiKey and smart card devices can be the
added second factor.
The libpam-u2f
package contains the PAM
library module and the needed
commands on Debian, Ubuntu, and derivatives.
Let's see how to set up YubiKey authentication
with the pam_u2f.so
PAM library.
U2F — Getting Started
The YubiKey contains a secp256r1 elliptic curve key pair (a.k.a. prime256v1 or NIST P-256). The public key is in the form of a certificate signed by Yubico. Verifying that certificate proves that the device was made by Yubico, giving the verifier confidence that the algorithms are implemented properly, certified by the FIDO Alliance.
To use semi-formal terminology, the user with the YubiKey is the principal, the entity that wants to authenticate or prove their claimed identity.
The various PAM-aware services running on the
Linux operating system are the
authenticators, entities that verify
the principal's claimed identity.
We might consider a Linux server to be a generalized
authenticator, hosting several services —
text console with login
,
graphical console with gdm
,
remote connections with sshd
,
and so on.
Each of those would have its own PAM file in
/etc/pam.d/
telling it how to authenticate users.
The Linux server registers the user's device, recording the fact that they own a specific YubiKey device. Starting an authentication event, the user connects their device electrically through a USB port or by radio through NFC or Near-Field Communication.
Now, in an overly simplified design...
When it's time to authenticate a user, the Linux server generates a random challenge and sends it to the device. The device generates a digital signature for the challenge, using its embedded private key, and sends the signature and its certificate back. The Linux system could first verify the certificate, showing it's really the public key of that device and thus belongs to that user. Then it could verify the digital signature over the randomly generated challenge, showing that the device contains the correct private key.
The problem is that if you use the device for multiple accounts, a breach of one could become a breach of all of them. Several YubiKey models are available, and all are small. But at US$ 20–70, users won't want to have to own one for each account.
Improving the Design
During the registration, the Linux server sends an
origin specifying the server to which
the user will authenticate,
an application ID specifying which
application on that server, and a random seed.
The origin might be pam://servername
,
and the appplication ID might be
pam://login
or pam://sshd
,
or perhaps just
pam://servername
again for the application ID.
In that last case, that one registered identity would work
for all applications on that origin, or server.
The YubiKey device then generates a new unique key pair for that origin and application. That new key pair is called the Registering Dependent Keys. This new key pair is used for this origin–application identity, so the one device supports its owner's many specific identities across multiple services running on multiple systems.
The server keeps a record for that user. That record includes their user name, the key handle specifying which key pair, and the public key of that pair.
At authentication time, the device is told which key to use to generate the signature.
Registering a User
pamu2fcfg
manual
You use the pamu2fcfg
command to
register a user.
By default the origin will be pam://$HOSTNAME
and the application ID will be the same.
The user name will be the same as the person running
the registration program.
Command-line parameters allow you to specify details.
The command outputs one very long line with no newline
at the end, formatted as:
Username:KeyHandle:PublicKey
.
Let's do this for a user named cromwell
on a system named laptop
:
# pamu2fcfg --origin=pam://laptop --username=cromwell ; echo cromwell:mUXDuyrXnRitucPGhB__UFH7hOCSKInTLMNLIPOvy1ZNhjqAx0cxA7NELmoYYmpvPwLs9KsHBAzmBWWM-GdloA,0422aadcae1c953a27e9451f55274188bb4665e84f56d5c900bbc08cd1a790a6bdaaa08a0a6dc7929a34ab87eb13a307d0d9f0f9798f680d3307fae4581b2b0ea3 \---+--/ \-------------------------------------------+----------------------------------------/ \---------------------------------------------------------------+----------------------------------------------------------------/ username key handle public key
The output is different each time you run the command. This is because each time the YubiKey device generates a new key pair based on the origin, application ID, and the random seed.
# pamu2fcfg --origin=pam://laptop --username=cromwell ; echo cromwell:9tAYwte2AqtdwvfqY2p9yqxlY1WBWM71uxA19nyM8-brl5KnSaDWbBET7m_MUDosKk5CcTLQ4UNaGBwoEjk4pQ,04aab5969e74c5b66bccfb3bc3c5767b57cf4a776ca6ca7c8d8e3bc9f4bf0326beec77ec70934c5388674a20e69c4dc71269ec0a57ac2f6f28419cc87f1a0be875 # pamu2fcfg --origin=pam://laptop --username=cromwell ; echo cromwell:Wjybc8zDNmrbYCpVX1ZR_B2RvpYFSI_NfxURqTit5jSmpgxthwZWDEtyf9GsRba6SrNgNu4MqbnJi5VFxtJs4w,04f76bf1dca36068a7d7547e7c61d98e3fb9cfb23d53e7d549bbc3123a204c28afaaa41bf115f6185c748538fee01b6de7237cc774203b90cfa9fe43254c5a64b3 # pamu2fcfg --origin=pam://laptop --username=cromwell ; echo cromwell:EWnXSzNq6CbnemflNB-4oSAB0F8a8m4ajT1ZsiTOXhIS-pIJ0mOEwFMIaMbfo8RKCjbMwnuBhmAtj_orTlqEBg,0472d694c6fb214cfb0b4b0196cd029ff98f4e1fb51d66a841c52592a89b353e32df3524bb28ed7c2634b10bf98db1a5148d1f0da6ce1b37b73b673713ba5568fd # pamu2fcfg --origin=pam://laptop --username=cromwell ; echo cromwell:vmzOGnYnomcjuHYKVIu_kv9OeLS9p71ub1OPrROUx1wdDu0RKL7yHjtjFhEvqICy39R_4Rw1-wMn9vS4AQrQBA,048b6185c13745d3ceac42a34791b1a961651e68a77b04c3b28c61933b40a889189dc9322c36057bd4ae7758ad568221ad512cae91a5397b2b7a061a76debad857 # pamu2fcfg --origin=pam://laptop --username=cromwell ; echo cromwell:CoZ-GrXSfZvwusIzQVKpzgfu7SrFokeHfwaCUY4Dfu4PaESuhZbGHTfvWnsLxVpWWowYxztmOo57McYlNuNC9A,0488b18a1f9b9eaad0dc058427600d9751786161baeb1477f8f7fd5062bb19cae040624adbce38e52a167f26d77bd9b3c4711d2b4507d59d361b8197d607ff274f # pamu2fcfg --origin=pam://laptop --username=cromwell ; echo cromwell:tYBy1lHWm35JS2vUdfxaL_8NNZjjPyzxTrGnIBUQQbUOBjkbYrflnuUKblh5yy35zDVmKt6tY3fxSqMajxpS-w,041ca0d0a6b7238bf2dbf5d56d58bb091d2b78aab7bdb420b16eb4b189cdf9914c32acde50386e94f784c644cf721237fb9528e9d91f36824439e2d29b4907b68e # pamu2fcfg --origin=pam://laptop --username=cromwell ; echo cromwell:Naxyr8MTqYcC_J0XrbnsAdxqdSBMCfUk25ePx7E491QXbXuyH5K4YjFa2ut6kV4GkG7e698Vi0gEvdwYmY5zgg,04a5f6df17855f0c206fe2cdeeb6d88533e6bb7b7e8452e4ff68d03d8fe679ec90a2ec12eaa78987550ea9e27ae086006d72c561d156e807b1caca85bbc7705450 # pamu2fcfg --origin=pam://laptop --username=cromwell ; echo cromwell:glTYFaOvNdzvu5sAi2vDz_kflMk9aKAtdUlIavsY50FaKoCChy331UV-TI6qbobEodcRNaCtS7ynl_HPZq4Bxw,0469a1bc0e85fc5f4888d5024d76e294bb2098916a586ad473bab927c00e239dee1e73eccd46d86e389e4a718a3e1baf6df49ad4a4b8b1e84f691e02843ef76d4d
Storing the Registration
The default is that each user has a one-line file
$HOME/.config/Yubico/u2f_keys
.
Alternatively, you could create one file somewhere under
/etc
with one line per user.
Then you would need to tell the PAM module
where to find this system-wide record of users'
uniquely generated public keys.
Configuring PAM
The file /etc/pam.d/common-auth
is included by several service files on Debian and Ubuntu.
It contains the following when you first install the system.
# # /etc/pam.d/common-auth - authentication settings common to all services # # This file is included from other service-specific PAM config files, # and should contain a list of the authentication modules that define # the central authentication scheme for use on the system # (e.g., /etc/shadow, LDAP, Kerberos, etc.). The default is to use the # traditional Unix authentication mechanisms. # # As of pam 1.0.1-6, this file is managed by pam-auth-update by default. # To take advantage of this, it is recommended that you configure any # local modules either before or after the default block, and use # pam-auth-update to manage selection of other modules. See # pam-auth-update(8) for details. # here are the per-package modules (the "Primary" block) auth [success=1 default=ignore] pam_unix.so nullok_secure # here's the fallback if no module succeeds auth requisite pam_deny.so # prime the stack with a positive return value if there isn't one already; # this avoids us returning an error just because nothing sets a success code # since the modules above will each just jump around auth required pam_permit.so # and here are more per-package modules (the "Additional" block) # end of pam-auth-update config
You can greatly simplify the file and require both YubiKey and password authentication:
# # /etc/pam.d/common-auth - authentication settings common to all services # # This file is included from other service-specific PAM config files, # and should contain a list of the authentication modules that define # the central authentication scheme for use on the system # (e.g., /etc/shadow, LDAP, Kerberos, etc.). The default is to use the # traditional Unix authentication mechanisms. # # WARNING: Do NOT use pam-auth-update as it will change this file # and destroy your settings. # Ask for the password and then for the token, failing at the end # if either is wrong. auth required pam_unix.so auth required pam_u2f.so cue
Or, if you want to allow either YubiKey or password authentication:
# # /etc/pam.d/common-auth - authentication settings common to all services # # This file is included from other service-specific PAM config files, # and should contain a list of the authentication modules that define # the central authentication scheme for use on the system # (e.g., /etc/shadow, LDAP, Kerberos, etc.). The default is to use the # traditional Unix authentication mechanisms. # # WARNING: Do NOT use pam-auth-update as it will change this file # and destroy your settings. # It either UNIX password or YubiKey succeeds, this immediately exits # with success. If neither succeeds, this fails. auth sufficient pam_unix.so auth sufficient pam_u2f.so cue auth required pam_deny.so
See the
pam_u2f(8)
manual page
for more on PAM module options and parameters.
You can add the debug
parameter
to get helpful troubleshooting information.
Going Deeper: Verbose U2F Authentication
We'll start a script session to capture this output.
Let's require the password first and then the token,
with the token in debug mode with lots of narrative output.
Then we'll run the login
program
and authenticate with a configured user account.
# script u2f-debug-output
Script started, file is u2f-debug-output
# cat /etc/pam.d/common-auth
auth required pam_unix.so
auth required pam_u2f.so cue debug
# cat ~cromwell/.config/Yubico/u2f_keys
cromwell:vsmDodhUsAc7j8HfnNYcWokggFRltEb6DgwvB_02Seja55XL5k0BV9eRp9ydJZqgVIbO8hjHnm1pCJDdT7xlFQ,041205c9eb8d0d297ee8cc82d7a592645a5d55288c5d203191ebbcee46422aca69e3cf2ee591361fceb28c5dbe59bcfa7fe5e593bbbfb8e10cd11f1f45160311c4
# login
laptop login: cromwell
Password: ØØØØØØØØØØØØØØØ
debug(pam_u2f): ../pam-u2f.c:99 (parse_cfg): called.
debug(pam_u2f): ../pam-u2f.c:100 (parse_cfg): flags 0 argc 2
debug(pam_u2f): ../pam-u2f.c:102 (parse_cfg): argv[0]=cue
debug(pam_u2f): ../pam-u2f.c:102 (parse_cfg): argv[1]=debug
debug(pam_u2f): ../pam-u2f.c:104 (parse_cfg): max_devices=0
debug(pam_u2f): ../pam-u2f.c:105 (parse_cfg): debug=1
debug(pam_u2f): ../pam-u2f.c:106 (parse_cfg): interactive=0
debug(pam_u2f): ../pam-u2f.c:107 (parse_cfg): cue=1
debug(pam_u2f): ../pam-u2f.c:108 (parse_cfg): nodetect=0
debug(pam_u2f): ../pam-u2f.c:109 (parse_cfg): manual=0
debug(pam_u2f): ../pam-u2f.c:110 (parse_cfg): nouserok=0
debug(pam_u2f): ../pam-u2f.c:111 (parse_cfg): openasuser=0
debug(pam_u2f): ../pam-u2f.c:112 (parse_cfg): alwaysok=0
debug(pam_u2f): ../pam-u2f.c:113 (parse_cfg): authfile=(null)
debug(pam_u2f): ../pam-u2f.c:114 (parse_cfg): authpending_file=(null)
debug(pam_u2f): ../pam-u2f.c:115 (parse_cfg): origin=(null)
debug(pam_u2f): ../pam-u2f.c:116 (parse_cfg): appid=(null)
debug(pam_u2f): ../pam-u2f.c:117 (parse_cfg): prompt=(null)
debug(pam_u2f): ../pam-u2f.c:169 (pam_sm_authenticate): Origin not specified, using "pam://laptop"
debug(pam_u2f): ../pam-u2f.c:181 (pam_sm_authenticate): Appid not specified, using the same value of origin (pam://laptop)
debug(pam_u2f): ../pam-u2f.c:192 (pam_sm_authenticate): Maximum devices number not set. Using default (24)
debug(pam_u2f): ../pam-u2f.c:210 (pam_sm_authenticate): Requesting authentication for user cromwell
debug(pam_u2f): ../pam-u2f.c:221 (pam_sm_authenticate): Found user cromwell
debug(pam_u2f): ../pam-u2f.c:222 (pam_sm_authenticate): Home directory for cromwell is /home/cromwell
debug(pam_u2f): ../pam-u2f.c:229 (pam_sm_authenticate): Variable XDG_CONFIG_HOME is not set. Using default value ($HOME/.config/)
debug(pam_u2f): ../pam-u2f.c:265 (pam_sm_authenticate): Using authentication file /home/cromwell/.config/Yubico/u2f_keys
debug(pam_u2f): ../pam-u2f.c:278 (pam_sm_authenticate): Dropping privileges
debug(pam_u2f): ../pam-u2f.c:284 (pam_sm_authenticate): Switched to uid 1001
debug(pam_u2f): ../util.c:105 (get_devices_from_authfile): Authorization line: cromwell:vsmDodhUsAc7j8HfnNYcWokggFRltEb6DgwvB_02Seja55XL5k0BV9eRp9ydJZqgVIbO8hjHnm1pCJDdT7xlFQ,041205c9eb8d0d297ee8cc82d7a592645a5d55288c5d203191ebbcee46422aca69e3cf2ee591361fceb28c5dbe59bcfa7fe5e593bbbfb8e10cd11f1f45160311c4
debug(pam_u2f): ../util.c:110 (get_devices_from_authfile): Matched user: cromwell
debug(pam_u2f): ../util.c:137 (get_devices_from_authfile): KeyHandle for device number 1: vsmDodhUsAc7j8HfnNYcWokggFRltEb6DgwvB_02Seja55XL5k0BV9eRp9ydJZqgVIbO8hjHnm1pCJDdT7xlFQ
debug(pam_u2f): ../util.c:156 (get_devices_from_authfile): publicKey for device number 1: 041205c9eb8d0d297ee8cc82d7a592645a5d55288c5d203191ebbcee46422aca69e3cf2ee591361fceb28c5dbe59bcfa7fe5e593bbbfb8e10cd11f1f45160311c4
debug(pam_u2f): ../util.c:167 (get_devices_from_authfile): Length of key number 1 is 65
debug(pam_u2f): ../util.c:194 (get_devices_from_authfile): Found 1 device(s) for user cromwell
debug(pam_u2f): ../pam-u2f.c:295 (pam_sm_authenticate): Restored privileges
debug(pam_u2f): ../pam-u2f.c:340 (pam_sm_authenticate): Using file '/var/run/user/0/pam-u2f-authpending' for emitting touch request notifications
USB send: 00ffffffff8600089d98a5ce497607c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USB write returned 65
now trying with timeout 2
USB read rc read 64
USB recv: ffffffff8600119d98a5ce497607c000180002020403070100000000000000000000000000000000000000000000000000000000000000000000000000000000
device /dev/hidraw1 discovered as 'Yubikey 4 OTP+U2F+CCID'
version (Interface, Major, Minor, Build): 2, 4, 3, 7 capFlags: 1
debug(pam_u2f): ../util.c:277 (do_authentication): Device max index is 0
debug(pam_u2f): ../util.c:308 (do_authentication): Attempting authentication with device number 1
debug(pam_u2f): ../util.c:332 (do_authentication): Challenge: { "keyHandle": "vsmDodhUsAc7j8HfnNYcWokggFRltEb6DgwvB_02Seja55XL5k0BV9eRp9ydJZqgVIbO8hjHnm1pCJDdT7xlFQ", "version": "U2F_V2", "challenge": "9p4mfQSs-TJtbqoFIQj8be8gzJTjOzr3L_cbCGSbbtY", "appId": "pam:\/\/laptop" }
JSON: { "keyHandle": "vsmDodhUsAc7j8HfnNYcWokggFRltEb6DgwvB_02Seja55XL5k0BV9eRp9ydJZqgVIbO8hjHnm1pCJDdT7xlFQ", "version": "U2F_V2", "challenge": "9p4mfQSs-TJtbqoFIQj8be8gzJTjOzr3L_cbCGSbbtY", "appId": "pam:\/\/laptop" }
JSON challenge URL-B64: 9p4mfQSs-TJtbqoFIQj8be8gzJTjOzr3L_cbCGSbbtY
client data: { "challenge": "9p4mfQSs-TJtbqoFIQj8be8gzJTjOzr3L_cbCGSbbtY", "origin": "pam:\/\/laptop", "typ": "navigator.id.getAssertion" }
JSON: { "keyHandle": "vsmDodhUsAc7j8HfnNYcWokggFRltEb6DgwvB_02Seja55XL5k0BV9eRp9ydJZqgVIbO8hjHnm1pCJDdT7xlFQ", "version": "U2F_V2", "challenge": "9p4mfQSs-TJtbqoFIQj8be8gzJTjOzr3L_cbCGSbbtY", "appId": "pam:\/\/laptop" }
JSON app_id pam://laptop
JSON: { "keyHandle": "vsmDodhUsAc7j8HfnNYcWokggFRltEb6DgwvB_02Seja55XL5k0BV9eRp9ydJZqgVIbO8hjHnm1pCJDdT7xlFQ", "version": "U2F_V2", "challenge": "9p4mfQSs-TJtbqoFIQj8be8gzJTjOzr3L_cbCGSbbtY", "appId": "pam:\/\/laptop" }
JSON keyHandle URL-B64: vsmDodhUsAc7j8HfnNYcWokggFRltEb6DgwvB_02Seja55XL5k0BV9eRp9ydJZqgVIbO8hjHnm1pCJDdT7xlFQ
USB send: 000018000283008a00020700000081330dfd388a6376c74e1a060c57f4a67a180e9de6cec9b6c85a72486d48995705a9a12dac5883bc1247c0646b263e008ed6
USB write returned 65
USB send: 000018000200963cf7da28a181ce80e25874fa9540bec983a1d854b0073b8fc1df9cd61c5a8920805465b446fa0e0c2f07fd3649e8dae795cbe64d0157d791a7
USB write returned 65
USB send: 0000180002019d259aa05486cef218c79e6d690890dd4fbc65150000000000000000000000000000000000000000000000000000000000000000000000000000
USB write returned 65
now trying with timeout 2
now trying with timeout 4
now trying with timeout 8
now trying with timeout 16
USB read rc read 64
USB recv: 00180002830002698500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USB data (len 2): 6985
Please touch the device.
JSON: { "keyHandle": "vsmDodhUsAc7j8HfnNYcWokggFRltEb6DgwvB_02Seja55XL5k0BV9eRp9ydJZqgVIbO8hjHnm1pCJDdT7xlFQ", "version": "U2F_V2", "challenge": "9p4mfQSs-TJtbqoFIQj8be8gzJTjOzr3L_cbCGSbbtY", "appId": "pam:\/\/laptop" }
JSON challenge URL-B64: 9p4mfQSs-TJtbqoFIQj8be8gzJTjOzr3L_cbCGSbbtY
client data: { "challenge": "9p4mfQSs-TJtbqoFIQj8be8gzJTjOzr3L_cbCGSbbtY", "origin": "pam:\/\/laptop", "typ": "navigator.id.getAssertion" }
JSON: { "keyHandle": "vsmDodhUsAc7j8HfnNYcWokggFRltEb6DgwvB_02Seja55XL5k0BV9eRp9ydJZqgVIbO8hjHnm1pCJDdT7xlFQ", "version": "U2F_V2", "challenge": "9p4mfQSs-TJtbqoFIQj8be8gzJTjOzr3L_cbCGSbbtY", "appId": "pam:\/\/laptop" }
JSON app_id pam://laptop
JSON: { "keyHandle": "vsmDodhUsAc7j8HfnNYcWokggFRltEb6DgwvB_02Seja55XL5k0BV9eRp9ydJZqgVIbO8hjHnm1pCJDdT7xlFQ", "version": "U2F_V2", "challenge": "9p4mfQSs-TJtbqoFIQj8be8gzJTjOzr3L_cbCGSbbtY", "appId": "pam:\/\/laptop" }
JSON keyHandle URL-B64: vsmDodhUsAc7j8HfnNYcWokggFRltEb6DgwvB_02Seja55XL5k0BV9eRp9ydJZqgVIbO8hjHnm1pCJDdT7xlFQ
USB send: 000018000283008a00020300000081330dfd388a6376c74e1a060c57f4a67a180e9de6cec9b6c85a72486d48995705a9a12dac5883bc1247c0646b263e008ed6
USB write returned 65
USB send: 000018000200963cf7da28a181ce80e25874fa9540bec983a1d854b0073b8fc1df9cd61c5a8920805465b446fa0e0c2f07fd3649e8dae795cbe64d0157d791a7
USB write returned 65
USB send: 0000180002019d259aa05486cef218c79e6d690890dd4fbc65150000000000000000000000000000000000000000000000000000000000000000000000000000
USB write returned 65
now trying with timeout 2
now trying with timeout 4
now trying with timeout 8
now trying with timeout 16
USB read rc read 64
USB recv: 00180002830002698500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USB data (len 2): 6985
USB send: 000018000283008a00020300000081330dfd388a6376c74e1a060c57f4a67a180e9de6cec9b6c85a72486d48995705a9a12dac5883bc1247c0646b263e008ed6
USB write returned 65
USB send: 000018000200963cf7da28a181ce80e25874fa9540bec983a1d854b0073b8fc1df9cd61c5a8920805465b446fa0e0c2f07fd3649e8dae795cbe64d0157d791a7
USB write returned 65
USB send: 0000180002019d259aa05486cef218c79e6d690890dd4fbc65150000000000000000000000000000000000000000000000000000000000000000000000000000
USB write returned 65
now trying with timeout 2
now trying with timeout 4
now trying with timeout 8
USB read rc read 64
USB recv: 00180002830002698500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USB data (len 2): 6985
USB send: 000018000283008a00020300000081330dfd388a6376c74e1a060c57f4a67a180e9de6cec9b6c85a72486d48995705a9a12dac5883bc1247c0646b263e008ed6
USB write returned 65
USB send: 000018000200963cf7da28a181ce80e25874fa9540bec983a1d854b0073b8fc1df9cd61c5a8920805465b446fa0e0c2f07fd3649e8dae795cbe64d0157d791a7
USB write returned 65
USB send: 0000180002019d259aa05486cef218c79e6d690890dd4fbc65150000000000000000000000000000000000000000000000000000000000000000000000000000
USB write returned 65
now trying with timeout 2
now trying with timeout 4
now trying with timeout 8
now trying with timeout 16
now trying with timeout 32
now trying with timeout 64
USB read rc read 64
USB recv: 0018000283004f01000000a0304602210099dad89f731dc1da6dfaecd9c59dbe1b38d8e0b9e5ff89351ee7e10b75b875de02210084f1064ad6087645168b856a
now trying with timeout 2
now trying with timeout 4
now trying with timeout 8
now trying with timeout 16
USB read rc read 64
USB recv: 0018000200229e8b557e14ed7a6ac8e592d838c180ebe120a2900000000000000000000000000000000000000000000000000000000000000000000000000000
USB data (len 79): 01000000a0304602210099dad89f731dc1da6dfaecd9c59dbe1b38d8e0b9e5ff89351ee7e10b75b875de02210084f1064ad6087645168b856a229e8b557e14ed7a6ac8e592d838c180ebe120a29000
JSON: { "keyHandle": "vsmDodhUsAc7j8HfnNYcWokggFRltEb6DgwvB_02Seja55XL5k0BV9eRp9ydJZqgVIbO8hjHnm1pCJDdT7xlFQ", "version": "U2F_V2", "challenge": "9p4mfQSs-TJtbqoFIQj8be8gzJTjOzr3L_cbCGSbbtY", "appId": "pam:\/\/laptop" }
JSON keyHandle URL-B64: vsmDodhUsAc7j8HfnNYcWokggFRltEb6DgwvB_02Seja55XL5k0BV9eRp9ydJZqgVIbO8hjHnm1pCJDdT7xlFQ
debug(pam_u2f): ../util.c:349 (do_authentication): Response: { "signatureData": "AQAAAKAwRgIhAJna2J9zHcHabfrs2cWdvhs42OC55f-JNR7n4Qt1uHXeAiEAhPEGStYIdkUWi4VqIp6LVX4U7XpqyOWS2DjBgOvhIKI", "clientData": "eyAiY2hhbGxlbmdlIjogIjlwNG1mUVNzLVRKdGJxb0ZJUWo4YmU4Z3pKVGpPenIzTF9jYkNHU2JidFkiLCAib3JpZ2luIjogInBhbTpcL1wvZGViaWFuIiwgInR5cCI6ICJuYXZpZ2F0b3IuaWQuZ2V0QXNzZXJ0aW9uIiB9", "keyHandle": "vsmDodhUsAc7j8HfnNYcWokggFRltEb6DgwvB_02Seja55XL5k0BV9eRp9ydJZqgVIbO8hjHnm1pCJDdT7xlFQ" }
signatureData: AQAAAKAwRgIhAJna2J9zHcHabfrs2cWdvhs42OC55f-JNR7n4Qt1uHXeAiEAhPEGStYIdkUWi4VqIp6LVX4U7XpqyOWS2DjBgOvhIKI
clientData: eyAiY2hhbGxlbmdlIjogIjlwNG1mUVNzLVRKdGJxb0ZJUWo4YmU4Z3pKVGpPenIzTF9jYkNHU2JidFkiLCAib3JpZ2luIjogInBhbTpcL1wvZGViaWFuIiwgInR5cCI6ICJuYXZpZ2F0b3IuaWQuZ2V0QXNzZXJ0aW9uIiB9
keyHandle: vsmDodhUsAc7j8HfnNYcWokggFRltEb6DgwvB_02Seja55XL5k0BV9eRp9ydJZqgVIbO8hjHnm1pCJDdT7xlFQ
signatureData Hex:
01 00 00 00 a0 30 46 02 21 00 99 da d8 9f 73 1d
c1 da 6d fa ec d9 c5 9d be 1b 38 d8 e0 b9 e5 ff
89 35 1e e7 e1 0b 75 b8 75 de 02 21 00 84 f1 06
4a d6 08 76 45 16 8b 85 6a 22 9e 8b 55 7e 14 ed
7a 6a c8 e5 92 d8 38 c1 80 eb e1 20 a2
clientData: { "challenge": "9p4mfQSs-TJtbqoFIQj8be8gzJTjOzr3L_cbCGSbbtY", "origin": "pam:\/\/laptop", "typ": "navigator.id.getAssertion" }
debug(pam_u2f): ../pam-u2f.c:410 (pam_sm_authenticate): done. [Success]
Linux laptop 4.19.0-14-amd64 #1 SMP Debian 4.19.171-2 (2021-01-30) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
cromwell@laptop:~$ exit
# exit
Script done, file is u2f-debug-output
Troubleshooting
This should be very easy to set up, but simple mistakes happen. For a troubleshooting checklist:
-
The user's identity is, by default, defined in:
$HOME/.config/Yubico/u2f_keys
It would be easy to typeYubikey
instead ofYubico
, oru2f-keys
instead ofu2f_keys
, or otherwise misplace the file. -
That file needs a single line starting with their
user name.
If you create the file as
root
you will get output to authenticateroot
, not the user. If you didn't think to specify the user name on the command line, as shown above, edit the file. -
By default the key handle will have
pam://$HOSTNAME
encoded into it. If you generate the file on one machine but use it on another, or if you change the name of the host, it won't work.
If you still haven't noticed what's wrong, turn on the
debug
option and capture output, as shown above.
If the user's file is in the wrong place you will see something like the following. Note that from here forward, I have manually added color to highlight the diagnostic output, the PAM module doesn't make it this easy for you:
[...lines deleted...] debug(pam_u2f): ../pam-u2f.c:210 (pam_sm_authenticate): Requesting authentication for user cromwell debug(pam_u2f): ../pam-u2f.c:221 (pam_sm_authenticate): Found user cromwell debug(pam_u2f): ../pam-u2f.c:222 (pam_sm_authenticate): Home directory for cromwell is /home/cromwell debug(pam_u2f): ../pam-u2f.c:229 (pam_sm_authenticate): Variable XDG_CONFIG_HOME is not set. Using default value ($HOME/.config/) debug(pam_u2f): ../pam-u2f.c:265 (pam_sm_authenticate): Using authentication file /home/cromwell/.config/Yubico/u2f_keys debug(pam_u2f): ../pam-u2f.c:278 (pam_sm_authenticate): Dropping privileges debug(pam_u2f): ../pam-u2f.c:284 (pam_sm_authenticate): Switched to uid 1001 debug(pam_u2f): ../util.c:42 (get_devices_from_authfile): Cannot open file: /home/cromwell/.config/Yubico/u2f_keys (No such file or directory) debug(pam_u2f): ../pam-u2f.c:295 (pam_sm_authenticate): Restored privileges debug(pam_u2f): ../pam-u2f.c:310 (pam_sm_authenticate): Unable to get devices from file /home/cromwell/.config/Yubico/u2f_keys debug(pam_u2f): ../pam-u2f.c:410 (pam_sm_authenticate): done. [Authentication service cannot retrieve authentication info] [...lines deleted...]
If there's a file in the right place for the user but it contains the wrong name, you will see something like the following:
[...lines deleted...] debug(pam_u2f): ../pam-u2f.c:210 (pam_sm_authenticate): Requesting authentication for user cromwell debug(pam_u2f): ../pam-u2f.c:221 (pam_sm_authenticate): Found user cromwell debug(pam_u2f): ../pam-u2f.c:222 (pam_sm_authenticate): Home directory for cromwell is /home/cromwell debug(pam_u2f): ../pam-u2f.c:229 (pam_sm_authenticate): Variable XDG_CONFIG_HOME is not set. Using default value ($HOME/.config/) debug(pam_u2f): ../pam-u2f.c:265 (pam_sm_authenticate): Using authentication file /home/cromwell/.config/Yubico/u2f_keys debug(pam_u2f): ../pam-u2f.c:278 (pam_sm_authenticate): Dropping privileges debug(pam_u2f): ../pam-u2f.c:284 (pam_sm_authenticate): Switched to uid 1001 debug(pam_u2f): ../util.c:105 (get_devices_from_authfile): Authorization line: root:NyHjaySH8f9z8Z1BF5L6y04Bwp1UYbh1vMdGSm-FraPWxXriARptEYQYLI8m7EDqp8rfFyzl8mvtK5yftoVu_Q,04df67960d7d9119cd2c56f57a7d40bbc3eee08a7f01bec0e0923b00e4a2b5eb764b9c1c7fb4d25c0f513498c7a2fe77594a61310d5e8a79d68ce1b3d17de7ed4 debug(pam_u2f): ../util.c:194 (get_devices_from_authfile): Found 0 device(s) for user cromwell debug(pam_u2f): ../pam-u2f.c:295 (pam_sm_authenticate): Restored privileges debug(pam_u2f): ../pam-u2f.c:314 (pam_sm_authenticate): Found no devices. Aborting. [...lines deleted...]
If there's a file in the right place with the right name, but the wrong origin (that is, host name), you will see something like the following. This will appear further down the output than the above examples, only appearing after you press the blinking button. It is only then that the device generates the signature, which includes the origin associated with the key:
[...lines deleted...]
debug(pam_u2f): ../util.c:368 (do_authentication): Device for this keyhandle is not present
USB send: 00001700038100010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USB write returned 65
now trying with timeout 2
USB read rc read 64
USB recv: 00170003810001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
debug(pam_u2f): ../pam-u2f.c:371 (pam_sm_authenticate): do_authentication returned -2
debug(pam_u2f): ../pam-u2f.c:410 (pam_sm_authenticate): done. [Authentication failure]
Suggestion: To make the authentication portable across several systems, you might generate the user files specifying a site-wide origin. Then specify that same origin in the PAM configuration:
# ( pamu2fcfg --origin=pam://headquarters --username=cromwell ; echo ) > ~cromwell/.config/Yubico/u2f_keys # grep pam_u2f.so /etc/pam.d/common-auth auth required pam_u2f.so cue origin=pam://headquarters
Going Deeper: Verbose Registration
To see more of what's happening,
add the --debug
option.
The hostname is already set to laptop
so
we don't really need to specify the origin or application ID.
You will see that the device returns its certificate.
- The Subject (device) has a prime256v1 elliptic curve key pair.
-
The 256-bit public key of that pair
(
04:4c:ac:...:e8:bb:85
) is contained in the certificate. - The certificate was signed at the factory by the Issuer, Yubico U2F Root CA, using a SHA256–RSA signature.
The block "registrationData Hex" just before the certificate is what the device has generated for this event. It created a new key pair based on the random seed sent from the application, and then created a certificate containing that public key and the origin inside. That certificate was signed by the device key, for which we have a certificate of its public key signed by the manufacturer. So there's your trust chain.
# pamu2fcfg --username=cromwell --debug ; echo USB send: 00ffffffff8600089c25f6f7538d23ea000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 USB write returned 65 now trying with timeout 2 USB read rc read 64 USB recv: ffffffff8600119c25f6f7538d23ea00150003020403070100000000000000000000000000000000000000000000000000000000000000000000000000000000 device /dev/hidraw1 discovered as 'Yubikey 4 OTP+U2F+CCID' version (Interface, Major, Minor, Build): 2, 4, 3, 7 capFlags: 1 JSON: { "challenge": "Xp9t3n9mZql9Q-TvnToX41Awz_60pqTu4rlozqBrw60", "version": "U2F_V2", "appId": "pam:\/\/laptop" } JSON challenge URL-B64: Xp9t3n9mZql9Q-TvnToX41Awz_60pqTu4rlozqBrw60 client data: { "challenge": "Xp9t3n9mZql9Q-TvnToX41Awz_60pqTu4rlozqBrw60", "origin": "pam:\/\/laptop", "typ": "navigator.id.finishEnrollment" } JSON: { "challenge": "Xp9t3n9mZql9Q-TvnToX41Awz_60pqTu4rlozqBrw60", "version": "U2F_V2", "appId": "pam:\/\/laptop" } JSON app_id pam://laptop USB send: 000015000383004900010300000040efa1f4e3791e219fd680508355875773defabe421f4413a58a7098cfae85a8b1a9a12dac5883bc1247c0646b263e008ed6 USB write returned 65 USB send: 000015000300963cf7da28a181ce80e25874fa950000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 USB write returned 65 now trying with timeout 2 USB read rc read 64 USB recv: 00150003830002698500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 USB data (len 2): 6985 USB send: 000015000383004900010300000040efa1f4e3791e219fd680508355875773defabe421f4413a58a7098cfae85a8b1a9a12dac5883bc1247c0646b263e008ed6 USB write returned 65 USB send: 000015000300963cf7da28a181ce80e25874fa950000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 USB write returned 65 now trying with timeout 2 USB read rc read 64 USB recv: 00150003830002698500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 USB data (len 2): 6985 USB send: 000015000383004900010300000040efa1f4e3791e219fd680508355875773defabe421f4413a58a7098cfae85a8b1a9a12dac5883bc1247c0646b263e008ed6 USB write returned 65 USB send: 000015000300963cf7da28a181ce80e25874fa950000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 USB write returned 65 now trying with timeout 2 now trying with timeout 4 now trying with timeout 8 now trying with timeout 16 now trying with timeout 32 now trying with timeout 64 now trying with timeout 128 USB read rc read 64 USB recv: 0015000383031f050471576ddf3e14162c93a7eab869b9478b3147b157e42d2c8c10a73d749407516ab1a4c40b75141b6187ff18143672c95f5dee2cc009cd1d now trying with timeout 2 now trying with timeout 4 now trying with timeout 8 now trying with timeout 16 now trying with timeout 32 USB read rc read 64 USB recv: 0015000300fd1fe67e20242181fd40f5ef692acb68c427b91956484b7660e9c91944c133943e36a519c898490c6f9f627f1df6738e0d57ba3c8b498b0ce1ac85 now trying with timeout 2 now trying with timeout 4 USB read rc read 64 USB recv: 0015000301fc821581a87b6c569541ee79eb5e333082024f30820137a00302010202040d000b16300d06092a864886f70d01010b0500302e312c302a06035504 now trying with timeout 2 now trying with timeout 4 USB read rc read 64 USB recv: 001500030203132359756269636f2055324620526f6f742043412053657269616c203435373230303633313020170d3134303830313030303030305a180f3230 now trying with timeout 2 now trying with timeout 4 USB read rc read 64 USB recv: 00150003033530303930343030303030305a3031312f302d06035504030c2659756269636f205532462045452053657269616c20323339323537333430313537 now trying with timeout 2 USB read rc read 64 USB recv: 001500030436353237303059301306072a8648ce3d020106082a8648ce3d030107034200044cacfa6ed104ba194bd6e066d7e13fcc6a600f10d2485c7ea3dbd4 now trying with timeout 2 USB read rc read 64 USB recv: 00150003054cd0d50db251387ba3bd1ebae6dee6250a0558c6e9be6118a4438e5a435f1ed2eb0ce8bb85a33b3039302206092b0601040182c40a020415312e33 now trying with timeout 2 USB read rc read 64 USB recv: 00150003062e362e312e342e312e34313438322e312e353013060b2b0601040182e51c020101040403020520300d06092a864886f70d01010b05000382010100 now trying with timeout 2 USB read rc read 64 USB recv: 00150003078ec24da8819582e73084199c9f140afaea805ba29fcd024d3e14022196b01c21d1e63e0914b02f82c415921390b9456323ac7cc0e523ba1d75237f now trying with timeout 2 USB read rc read 64 USB recv: 00150003082669fc1f3acf5afcca54fffe982b91312773ef7e7014d617e7195ef8d2e4a1cb598f21ce0aa75de01f25817d27cf03623d9b9ffac758e5f87384b4 now trying with timeout 2 USB read rc read 64 USB recv: 001500030966b5ba5f0434e84cfe7bb4b4795a5218ea427a40a79ca59e6c54dc42cd2571467700a6d655ed84ac5f6c1ed392ade661e4047aa18b90933d042638 now trying with timeout 2 now trying with timeout 4 USB read rc read 64 USB recv: 001500030ae6c7a2fedc07ee2ae42a6e7c3cc40454ca3cbded5b157a1ef42bd09e8ca7a6d91480aae674cfed53dab679c97a5440f5598f4a942e2e3a51aa9245 now trying with timeout 2 now trying with timeout 4 USB read rc read 64 USB recv: 001500030b291a1b8fc790f72baf7971bfeeebad04ecc11d6f3045022100b604d9ae8190ddc136b3fe7700b3a7f805c898330f7d13ba3fce7ea4390b37650220 now trying with timeout 2 USB read rc read 64 USB recv: 001500030c4948abcedb0f1ada2e61a9eab45bdf616e27d42945fe1bc368c2173ee62cf404900000000000000000000000000000000000000000000000000000 USB data (len 799): 050471576ddf3e14162c93a7eab869b9478b3147b157e42d2c8c10a73d749407516ab1a4c40b75141b6187ff18143672c95f5dee2cc009cd1dfd1fe67e20242181fd40f5ef692acb68c427b91956484b7660e9c91944c133943e36a519c898490c6f9f627f1df6738e0d57ba3c8b498b0ce1ac85fc821581a87b6c569541ee79eb5e333082024f30820137a00302010202040d000b16300d06092a864886f70d01010b0500302e312c302a0603550403132359756269636f2055324620526f6f742043412053657269616c203435373230303633313020170d3134303830313030303030305a180f32303530303930343030303030305a3031312f302d06035504030c2659756269636f205532462045452053657269616c2032333932353733343031353736353237303059301306072a8648ce3d020106082a8648ce3d030107034200044cacfa6ed104ba194bd6e066d7e13fcc6a600f10d2485c7ea3dbd44cd0d50db251387ba3bd1ebae6dee6250a0558c6e9be6118a4438e5a435f1ed2eb0ce8bb85a33b3039302206092b0601040182c40a020415312e332e362e312e342e312e34313438322e312e353013060b2b0601040182e51c020101040403020520300d06092a864886f70d01010b050003820101008ec24da8819582e73084199c9f140afaea805ba29fcd024d3e14022196b01c21d1e63e0914b02f82c415921390b9456323ac7cc0e523ba1d75237f2669fc1f3acf5afcca54fffe982b91312773ef7e7014d617e7195ef8d2e4a1cb598f21ce0aa75de01f25817d27cf03623d9b9ffac758e5f87384b466b5ba5f0434e84cfe7bb4b4795a5218ea427a40a79ca59e6c54dc42cd2571467700a6d655ed84ac5f6c1ed392ade661e4047aa18b90933d042638e6c7a2fedc07ee2ae42a6e7c3cc40454ca3cbded5b157a1ef42bd09e8ca7a6d91480aae674cfed53dab679c97a5440f5598f4a942e2e3a51aa9245291a1b8fc790f72baf7971bfeeebad04ecc11d6f3045022100b604d9ae8190ddc136b3fe7700b3a7f805c898330f7d13ba3fce7ea4390b376502204948abcedb0f1ada2e61a9eab45bdf616e27d42945fe1bc368c2173ee62cf4049000 registrationData: BQRxV23fPhQWLJOn6rhpuUeLMUexV-QtLIwQpz10lAdRarGkxAt1FBthh_8YFDZyyV9d7izACc0d_R_mfiAkIYH9QPXvaSrLaMQnuRlWSEt2YOnJGUTBM5Q-NqUZyJhJDG-fYn8d9nOODVe6PItJiwzhrIX8ghWBqHtsVpVB7nnrXjMwggJPMIIBN6ADAgECAgQNAAsWMA0GCSqGSIb3DQEBCwUAMC4xLDAqBgNVBAMTI1l1YmljbyBVMkYgUm9vdCBDQSBTZXJpYWwgNDU3MjAwNjMxMCAXDTE0MDgwMTAwMDAwMFoYDzIwNTAwOTA0MDAwMDAwWjAxMS8wLQYDVQQDDCZZdWJpY28gVTJGIEVFIFNlcmlhbCAyMzkyNTczNDAxNTc2NTI3MDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABEys-m7RBLoZS9bgZtfhP8xqYA8Q0khcfqPb1EzQ1Q2yUTh7o70euube5iUKBVjG6b5hGKRDjlpDXx7S6wzou4WjOzA5MCIGCSsGAQQBgsQKAgQVMS4zLjYuMS40LjEuNDE0ODIuMS41MBMGCysGAQQBguUcAgEBBAQDAgUgMA0GCSqGSIb3DQEBCwUAA4IBAQCOwk2ogZWC5zCEGZyfFAr66oBbop_NAk0-FAIhlrAcIdHmPgkUsC-CxBWSE5C5RWMjrHzA5SO6HXUjfyZp_B86z1r8ylT__pgrkTEnc-9-cBTWF-cZXvjS5KHLWY8hzgqnXeAfJYF9J88DYj2bn_rHWOX4c4S0ZrW6XwQ06Ez-e7S0eVpSGOpCekCnnKWebFTcQs0lcUZ3AKbWVe2ErF9sHtOSreZh5AR6oYuQkz0EJjjmx6L-3AfuKuQqbnw8xARUyjy97VsVeh70K9CejKem2RSAquZ0z-1T2rZ5yXpUQPVZj0qULi46UaqSRSkaG4_HkPcrr3lxv-7rrQTswR1vMEUCIQC2BNmugZDdwTaz_ncAs6f4BciYMw99E7o_zn6kOQs3ZQIgSUirztsPGtouYanqtFvfYW4n1ClF_hvDaMIXPuYs9AQ clientData: eyAiY2hhbGxlbmdlIjogIlhwOXQzbjltWnFsOVEtVHZuVG9YNDFBd3pfNjBwcVR1NHJsb3pxQnJ3NjAiLCAib3JpZ2luIjogInBhbTpcL1wvZGViaWFuIiwgInR5cCI6ICJuYXZpZ2F0b3IuaWQuZmluaXNoRW5yb2xsbWVudCIgfQ registrationData Hex: 05 04 71 57 6d df 3e 14 16 2c 93 a7 ea b8 69 b9 47 8b 31 47 b1 57 e4 2d 2c 8c 10 a7 3d 74 94 07 51 6a b1 a4 c4 0b 75 14 1b 61 87 ff 18 14 36 72 c9 5f 5d ee 2c c0 09 cd 1d fd 1f e6 7e 20 24 21 81 fd 40 f5 ef 69 2a cb 68 c4 27 b9 19 56 48 4b 76 60 e9 c9 19 44 c1 33 94 3e 36 a5 19 c8 98 49 0c 6f 9f 62 7f 1d f6 73 8e 0d 57 ba 3c 8b 49 8b 0c e1 ac 85 fc 82 15 81 a8 7b 6c 56 95 41 ee 79 eb 5e 33 30 82 02 4f 30 82 01 37 a0 03 02 01 02 02 04 0d 00 0b 16 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 2e 31 2c 30 2a 06 03 55 04 03 13 23 59 75 62 69 63 6f 20 55 32 46 20 52 6f 6f 74 20 43 41 20 53 65 72 69 61 6c 20 34 35 37 32 30 30 36 33 31 30 20 17 0d 31 34 30 38 30 31 30 30 30 30 30 30 5a 18 0f 32 30 35 30 30 39 30 34 30 30 30 30 30 30 5a 30 31 31 2f 30 2d 06 03 55 04 03 0c 26 59 75 62 69 63 6f 20 55 32 46 20 45 45 20 53 65 72 69 61 6c 20 32 33 39 32 35 37 33 34 30 31 35 37 36 35 32 37 30 30 59 30 13 06 07 2a 86 48 ce 3d 02 01 06 08 2a 86 48 ce 3d 03 01 07 03 42 00 04 4c ac fa 6e d1 04 ba 19 4b d6 e0 66 d7 e1 3f cc 6a 60 0f 10 d2 48 5c 7e a3 db d4 4c d0 d5 0d b2 51 38 7b a3 bd 1e ba e6 de e6 25 0a 05 58 c6 e9 be 61 18 a4 43 8e 5a 43 5f 1e d2 eb 0c e8 bb 85 a3 3b 30 39 30 22 06 09 2b 06 01 04 01 82 c4 0a 02 04 15 31 2e 33 2e 36 2e 31 2e 34 2e 31 2e 34 31 34 38 32 2e 31 2e 35 30 13 06 0b 2b 06 01 04 01 82 e5 1c 02 01 01 04 04 03 02 05 20 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 82 01 01 00 8e c2 4d a8 81 95 82 e7 30 84 19 9c 9f 14 0a fa ea 80 5b a2 9f cd 02 4d 3e 14 02 21 96 b0 1c 21 d1 e6 3e 09 14 b0 2f 82 c4 15 92 13 90 b9 45 63 23 ac 7c c0 e5 23 ba 1d 75 23 7f 26 69 fc 1f 3a cf 5a fc ca 54 ff fe 98 2b 91 31 27 73 ef 7e 70 14 d6 17 e7 19 5e f8 d2 e4 a1 cb 59 8f 21 ce 0a a7 5d e0 1f 25 81 7d 27 cf 03 62 3d 9b 9f fa c7 58 e5 f8 73 84 b4 66 b5 ba 5f 04 34 e8 4c fe 7b b4 b4 79 5a 52 18 ea 42 7a 40 a7 9c a5 9e 6c 54 dc 42 cd 25 71 46 77 00 a6 d6 55 ed 84 ac 5f 6c 1e d3 92 ad e6 61 e4 04 7a a1 8b 90 93 3d 04 26 38 e6 c7 a2 fe dc 07 ee 2a e4 2a 6e 7c 3c c4 04 54 ca 3c bd ed 5b 15 7a 1e f4 2b d0 9e 8c a7 a6 d9 14 80 aa e6 74 cf ed 53 da b6 79 c9 7a 54 40 f5 59 8f 4a 94 2e 2e 3a 51 aa 92 45 29 1a 1b 8f c7 90 f7 2b af 79 71 bf ee eb ad 04 ec c1 1d 6f 30 45 02 21 00 b6 04 d9 ae 81 90 dd c1 36 b3 fe 77 00 b3 a7 f8 05 c8 98 33 0f 7d 13 ba 3f ce 7e a4 39 0b 37 65 02 20 49 48 ab ce db 0f 1a da 2e 61 a9 ea b4 5b df 61 6e 27 d4 29 45 fe 1b c3 68 c2 17 3e e6 2c f4 04 Key handle length: 64 Certificate: Data: Version: 3 (0x2) Serial Number: 218106646 (0xd000b16) 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 23925734015765270 Subject Public Key Info: Public Key Algorithm: id-ecPublicKey Public-Key: (256 bit) pub: 04:4c:ac:fa:6e:d1:04:ba:19:4b:d6:e0:66:d7:e1: 3f:cc:6a:60:0f:10:d2:48:5c:7e:a3:db:d4:4c:d0: d5:0d:b2:51:38:7b:a3:bd:1e:ba:e6:de:e6:25:0a: 05:58:c6:e9:be:61:18:a4:43:8e:5a:43:5f:1e:d2: eb:0c:e8:bb:85 ASN1 OID: prime256v1 NIST CURVE: P-256 X509v3 extensions: 1.3.6.1.4.1.41482.2: 1.3.6.1.4.1.41482.1.5 1.3.6.1.4.1.45724.2.1.1: ... Signature Algorithm: sha256WithRSAEncryption 8e:c2:4d:a8:81:95:82:e7:30:84:19:9c:9f:14:0a:fa:ea:80: 5b:a2:9f:cd:02:4d:3e:14:02:21:96:b0:1c:21:d1:e6:3e:09: 14:b0:2f:82:c4:15:92:13:90:b9:45:63:23:ac:7c:c0:e5:23: ba:1d:75:23:7f:26:69:fc:1f:3a:cf:5a:fc:ca:54:ff:fe:98: 2b:91:31:27:73:ef:7e:70:14:d6:17:e7:19:5e:f8:d2:e4:a1: cb:59:8f:21:ce:0a:a7:5d:e0:1f:25:81:7d:27:cf:03:62:3d: 9b:9f:fa:c7:58:e5:f8:73:84:b4:66:b5:ba:5f:04:34:e8:4c: fe:7b:b4:b4:79:5a:52:18:ea:42:7a:40:a7:9c:a5:9e:6c:54: dc:42:cd:25:71:46:77:00:a6:d6:55:ed:84:ac:5f:6c:1e:d3: 92:ad:e6:61:e4:04:7a:a1:8b:90:93:3d:04:26:38:e6:c7:a2: fe:dc:07:ee:2a:e4:2a:6e:7c:3c:c4:04:54:ca:3c:bd:ed:5b: 15:7a:1e:f4:2b:d0:9e:8c:a7:a6:d9:14:80:aa:e6:74:cf:ed: 53:da:b6:79:c9:7a:54:40:f5:59:8f:4a:94:2e:2e:3a:51:aa: 92:45:29:1a:1b:8f:c7:90:f7:2b:af:79:71:bf:ee:eb:ad:04: ec:c1:1d:6f -----BEGIN CERTIFICATE----- MIICTzCCATegAwIBAgIEDQALFjANBgkqhkiG9w0BAQsFADAuMSwwKgYDVQQDEyNZ dWJpY28gVTJGIFJvb3QgQ0EgU2VyaWFsIDQ1NzIwMDYzMTAgFw0xNDA4MDEwMDAw MDBaGA8yMDUwMDkwNDAwMDAwMFowMTEvMC0GA1UEAwwmWXViaWNvIFUyRiBFRSBT ZXJpYWwgMjM5MjU3MzQwMTU3NjUyNzAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC AARMrPpu0QS6GUvW4GbX4T/MamAPENJIXH6j29RM0NUNslE4e6O9Hrrm3uYlCgVY xum+YRikQ45aQ18e0usM6LuFozswOTAiBgkrBgEEAYLECgIEFTEuMy42LjEuNC4x LjQxNDgyLjEuNTATBgsrBgEEAYLlHAIBAQQEAwIFIDANBgkqhkiG9w0BAQsFAAOC AQEAjsJNqIGVgucwhBmcnxQK+uqAW6KfzQJNPhQCIZawHCHR5j4JFLAvgsQVkhOQ uUVjI6x8wOUjuh11I38mafwfOs9a/MpU//6YK5ExJ3PvfnAU1hfnGV740uShy1mP Ic4Kp13gHyWBfSfPA2I9m5/6x1jl+HOEtGa1ul8ENOhM/nu0tHlaUhjqQnpAp5yl nmxU3ELNJXFGdwCm1lXthKxfbB7Tkq3mYeQEeqGLkJM9BCY45sei/twH7irkKm58 PMQEVMo8ve1bFXoe9CvQnoynptkUgKrmdM/tU9q2ecl6VED1WY9KlC4uOlGqkkUp GhuPx5D3K695cb/u660E7MEdbw== -----END CERTIFICATE----- clientData: { "challenge": "Xp9t3n9mZql9Q-TvnToX41Awz_60pqTu4rlozqBrw60", "origin": "pam:\/\/laptop", "typ": "navigator.id.finishEnrollment" } cromwell:9e9pKstoxCe5GVZIS3Zg6ckZRMEzlD42pRnImEkMb59ifx32c44NV7o8i0mLDOGshfyCFYGoe2xWlUHueeteMw,0471576ddf3e14162c93a7eab869b9478b3147b157e42d2c8c10a73d749407516ab1a4c40b75141b6187ff18143672c95f5dee2cc009cd1dfd1fe67e20242181fd