11package com .yubico .webauthn .attestation
22
3+ import com .yubico .internal .util .BinaryUtil
4+ import com .yubico .internal .util .CertificateParser
35import com .yubico .webauthn .TestAuthenticator
46import com .yubico .webauthn .data .ByteArray
57import org .bouncycastle .asn1 .DEROctetString
@@ -10,6 +12,7 @@ import org.scalatest.matchers.should.Matchers
1012import org .scalatestplus .junit .JUnitRunner
1113
1214import java .security .cert .X509Certificate
15+ import scala .jdk .OptionConverters .RichOptional
1316
1417@ RunWith (classOf [JUnitRunner ])
1518class CertificateUtilSpec extends AnyFunSpec with Matchers {
@@ -39,6 +42,36 @@ class CertificateUtilSpec extends AnyFunSpec with Matchers {
3942 result should equal(ByteArray .fromHex(" 00010203" ))
4043 }
4144
42- }
45+ it(" correctly parses the serial number from a real YubiKey enterprise attestation certificate." ) {
46+ val cert = CertificateParser .parsePem(""" -----BEGIN CERTIFICATE-----
47+ |MIIC8zCCAdugAwIBAgIJAKr/KiUzkKrgMA0GCSqGSIb3DQEBCwUAMC8xLTArBgNV
48+ |BAMMJFl1YmljbyBGSURPIFJvb3QgQ0EgU2VyaWFsIDQ1MDIwMzU1NjAgFw0yNDA1
49+ |MDEwMDAwMDBaGA8yMDYwMDQzMDAwMDAwMFowcDELMAkGA1UEBhMCU0UxEjAQBgNV
50+ |BAoMCVl1YmljbyBBQjEiMCAGA1UECwwZQXV0aGVudGljYXRvciBBdHRlc3RhdGlv
51+ |bjEpMCcGA1UEAwwgWXViaWNvIEZpZG8gRUUgKFNlcmlhbD0yODI5OTAwMykwWTAT
52+ |BgcqhkjOPQIBBggqhkjOPQMBBwNCAATImNkI1cwqkW5B3qNrY3pc8zBLhvGyfyfS
53+ |WCLrODSe8xaRPcZoXYGGwZ0Ua/Hp5nxyD+w1hjS9O9gx8mSDvp+zo4GZMIGWMBMG
54+ |CisGAQQBgsQKDQEEBQQDBQcBMBUGCysGAQQBguUcAQECBAYEBAGvzvswIgYJKwYB
55+ |BAGCxAoCBBUxLjMuNi4xLjQuMS40MTQ4Mi4xLjcwEwYLKwYBBAGC5RwCAQEEBAMC
56+ |AiQwIQYLKwYBBAGC5RwBAQQEEgQQuQ59wTFuT+6iWlamZqZw/jAMBgNVHRMBAf8E
57+ |AjAAMA0GCSqGSIb3DQEBCwUAA4IBAQAFEMXw1HUDC/TfMFxp2ZrmgQLa5fmzs2Jh
58+ |C22TUAuY26CYT5dmMUsS5aJd96MtC5gKS57h1auGr2Y4FMxQS9FJHzXAzAtYJfKh
59+ |j1uS2BSTXf9GULdFKcWvvv50kJ2VmXLge3UgHDBJ8LwrDlZFyISeMZ8jSbmrNu2c
60+ |8uNBBSfqdor+5H91L1brC9yYneHdxYk6YiEvDBxWjiMa9DQuySh/4a21nasgt0cB
61+ |prEbfFOLRDm7GDsRTPyefZjZ84yi4Ao+15x+7DM0UwudEVtjOWB2BJtJyxIkXXNF
62+ |iWFZaxezq0Xt2Kl2sYnMR97ynw/U4TzZDjgb56pN81oKz8Od9B/u
63+ |-----END CERTIFICATE-----""" .stripMargin)
64+
65+ val result =
66+ CertificateUtil
67+ .parseFidoSerNumExtension(cert)
68+ .toScala
69+ .map(new ByteArray (_))
4370
71+ result should equal(Some (ByteArray .fromHex(" 01AFCEFB" )))
72+
73+ // For YubiKeys, the sernum octet string represents a big-endian integer
74+ BinaryUtil .getUint32(result.get.getBytes) should be(28299003 )
75+ }
76+ }
4477}
0 commit comments