From ce274bf2b5d880770f97ac340fe7d910e077d01e Mon Sep 17 00:00:00 2001
From: Emil Lundberg <emil@yubico.com>
Date: Fri, 26 Mar 2021 19:28:12 +0100
Subject: [PATCH 1/2] Add tests of attestation metadata for new FIPS devices

---
 .../DeviceIdentificationSpec.scala            | 36 +++++++++++++-
 .../yubico/webauthn/test/RealExamples.scala   | 49 +++++++++++++++++++
 2 files changed, 84 insertions(+), 1 deletion(-)

diff --git a/webauthn-server-attestation/src/test/scala/com/yubico/webauthn/attestation/DeviceIdentificationSpec.scala b/webauthn-server-attestation/src/test/scala/com/yubico/webauthn/attestation/DeviceIdentificationSpec.scala
index acaa74e8f..65ae59ca9 100644
--- a/webauthn-server-attestation/src/test/scala/com/yubico/webauthn/attestation/DeviceIdentificationSpec.scala
+++ b/webauthn-server-attestation/src/test/scala/com/yubico/webauthn/attestation/DeviceIdentificationSpec.scala
@@ -73,6 +73,7 @@ class DeviceIdentificationSpec extends FunSpec with Matchers {
           .identity(testData.rp)
           .credentialRepository(Helpers.CredentialRepository.empty)
           .metadataService(new StandardMetadataService())
+          .allowUnrequestedExtensions(true)
           .build()
 
         val result = rp.finishRegistration(
@@ -85,7 +86,10 @@ class DeviceIdentificationSpec extends FunSpec with Matchers {
                 .user(testData.user)
                 .challenge(testData.attestation.challenge)
                 .pubKeyCredParams(
-                  List(PublicKeyCredentialParameters.ES256).asJava
+                  List(
+                    PublicKeyCredentialParameters.ES256,
+                    PublicKeyCredentialParameters.EdDSA,
+                  ).asJava
                 )
                 .build()
             )
@@ -150,6 +154,21 @@ class DeviceIdentificationSpec extends FunSpec with Matchers {
           Set(USB, NFC),
         )
       }
+
+      it("a YubiKey 5.4 NFC FIPS.") {
+        check(
+          "YubiKey 5/5C NFC FIPS",
+          RealExamples.YubikeyFips5Nfc,
+          Set(USB, NFC),
+        )
+      }
+      it("a YubiKey 5.4 Ci FIPS.") {
+        check(
+          "YubiKey 5Ci FIPS",
+          RealExamples.Yubikey5ciFips,
+          Set(USB, LIGHTNING),
+        )
+      }
     }
 
     describe("fails to identify") {
@@ -259,6 +278,21 @@ class DeviceIdentificationSpec extends FunSpec with Matchers {
           Set(USB, NFC),
         )
       }
+
+      it("a YubiKey 5.4 NFC FIPS.") {
+        check(
+          "YubiKey 5/5C NFC FIPS",
+          RealExamples.YubikeyFips5Nfc,
+          Set(USB, NFC),
+        )
+      }
+      it("a YubiKey 5.4 Ci FIPS.") {
+        check(
+          "YubiKey 5Ci FIPS",
+          RealExamples.Yubikey5ciFips,
+          Set(USB, LIGHTNING),
+        )
+      }
     }
   }
 
diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/test/RealExamples.scala b/webauthn-server-core/src/test/scala/com/yubico/webauthn/test/RealExamples.scala
index e0c932d46..766ecf416 100644
--- a/webauthn-server-core/src/test/scala/com/yubico/webauthn/test/RealExamples.scala
+++ b/webauthn-server-core/src/test/scala/com/yubico/webauthn/test/RealExamples.scala
@@ -460,4 +460,53 @@ object RealExamples {
     ),
   )
 
+  val YubikeyFips5Nfc = Example(
+    RelyingPartyIdentity.builder().id("demo.yubico.com").name("").build(),
+    UserIdentity
+      .builder()
+      .name("6vTZo5MBEbaH")
+      .displayName("6vTZo5MBEbaH")
+      .id(ByteArray.fromBase64("tabbiLeU61rCtgcNOC+9J6doMN8DQnm2IEaa4Ps+gqU="))
+      .build(),
+    AttestationExample(
+      """{"type":"webauthn.create","challenge":"BkRnXYHVbiUEJYPPcVAOig","origin":"https://demo.yubico.com","crossOrigin":false,"other_keys_can_be_added_here":"do not compare clientDataJSON against a template. See https://goo.gl/yabPex"}""",
+      ByteArray.fromBase64("o2NmbXRmcGFja2VkZ2F0dFN0bXSjY2FsZyZjc2lnWEcwRQIhAMrVMrCPZDK3RNFKKdDOYoSPsEqgSecbvfUIuPk84nIwAiA6VbneoEArKqgrwWnDcQi03kyWQrPmr3JqHtPUXNGitWN4NWOBWQLwMIIC7DCCAdSgAwIBAgIJAN1TJeaFJ6cVMA0GCSqGSIb3DQEBCwUAMC4xLDAqBgNVBAMTI1l1YmljbyBVMkYgUm9vdCBDQSBTZXJpYWwgNDU3MjAwNjMxMCAXDTE0MDgwMTAwMDAwMFoYDzIwNTAwOTA0MDAwMDAwWjBvMQswCQYDVQQGEwJTRTESMBAGA1UECgwJWXViaWNvIEFCMSIwIAYDVQQLDBlBdXRoZW50aWNhdG9yIEF0dGVzdGF0aW9uMSgwJgYDVQQDDB9ZdWJpY28gVTJGIEVFIFNlcmlhbCAxNzEzNzIyMzMzMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEDeoY3vFmcuLvf1SL2oqIV5WaVs9VGyB4GPmtxdHY84v/+R2wtLKvAfjIH9eTIq3+Ev3+UQLipTY0Bb9Xn9Sp3KOBlDCBkTATBgorBgEEAYLECg0BBAUEAwUEAjAQBgkrBgEEAYLECgwEAwIBBDAiBgkrBgEEAYLECgIEFTEuMy42LjEuNC4xLjQxNDgyLjEuNzATBgsrBgEEAYLlHAIBAQQEAwIEMDAhBgsrBgEEAYLlHAEBBAQSBBDB+aC8HdJASrJ/jikEekP9MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAGl5dmZIe5GOHFOAvVUaWFWyet89UCHWKmLBTXXfuoPwYqatxGhVqIeiV4nAuFF127294SzJcMgzycToui5/g8OUonTvs9xWF9yH23fXjGcBWoGErlF7DqkycOz2NtjPhGwEfBnE++0/KRc/IN6bu7u/XPXNwNmCLcg0reERI23NO/ZftcWebjRBCwY3p6l0ahalKmrgqOi7bhU1AjbHmiEvJgeBcpZphS87eikierMO5PmwvdbV3okNseEoaeoHDDQ7Av6RwCtKCXwYupRs6sULgUwo0fz2znURA+zSuTzK4iZ/hmQvRVJtQBPtfpwBEmNEdwwZ1A+VxfspsYzA7AVoYXV0aERhdGFYn8Rs74KtG1Rkd1kdAIsIdZ7D5tLstPOUdL/qaWmSXQO3xQAAAALB+aC8HdJASrJ/jikEekP9ADCoKvXSwuTSIXADOmvBwyJiDqQ6hh3epKxT2gFcv7/fe7KF6ZidYuy5hytIti+jyUSkAQEDJyAGIVggqCr10sLk0iFwAzprwb1UlYO/I5e1odNDyARvWzyHZkuha2NyZWRQcm90ZWN0Ag=="),
+    ),
+    AssertionExample(
+      id = ByteArray.fromBase64Url(
+        "qCr10sLk0iFwAzprwcMiYg6kOoYd3qSsU9oBXL-_33uyhemYnWLsuYcrSLYvo8lE"
+      ),
+      clientData = """{"type":"webauthn.get","challenge":"P0MvFaK3Bz-YYVYfCXfBig","origin":"https://demo.yubico.com","crossOrigin":false}""",
+      authDataBytes = ByteArray.fromBase64(
+        "xGzvgq0bVGR3WR0Aiwh1nsPm0uy085R0v+ppaZJdA7cFAAAAAw=="
+      ),
+      sig =
+        ByteArray.fromBase64("Q0omzU9kPFnxd9njE5+fWLDDFxPIXRrPJ3fSGniU2+UHp1NUZJtMwc4iddbXiYNZ2GN5frrG3tf72oAoI+i3BQ=="),
+    ),
+  )
+
+  val Yubikey5ciFips = Example(
+    RelyingPartyIdentity.builder().id("demo.yubico.com").name("").build(),
+    UserIdentity
+      .builder()
+      .name("6J8bPm5pgZxx")
+      .displayName("6J8bPm5pgZxx")
+      .id(ByteArray.fromBase64("cj5f7W52d8rucMRXw+F+k/tMcMjRZbWNmmayWQ/s1hY="))
+      .build(),
+    AttestationExample(
+      """{"type":"webauthn.create","challenge":"hnZ_h1C2W1hIvTv-TczSDQ","origin":"https://demo.yubico.com","crossOrigin":false}""",
+      ByteArray.fromBase64("o2NmbXRmcGFja2VkZ2F0dFN0bXSjY2FsZyZjc2lnWEcwRQIgNjV3981oAhwpWDaw0VT7o/KK/OZ4MJF1Gx3p68dfgSkCIQClgMNxOuNeWlX3OEekplBvZyEdnjrgXHPK4+qxbgb6yWN4NWOBWQLwMIIC7DCCAdSgAwIBAgIJAJt5F3hRiVnmMA0GCSqGSIb3DQEBCwUAMC4xLDAqBgNVBAMTI1l1YmljbyBVMkYgUm9vdCBDQSBTZXJpYWwgNDU3MjAwNjMxMCAXDTE0MDgwMTAwMDAwMFoYDzIwNTAwOTA0MDAwMDAwWjBvMQswCQYDVQQGEwJTRTESMBAGA1UECgwJWXViaWNvIEFCMSIwIAYDVQQLDBlBdXRoZW50aWNhdG9yIEF0dGVzdGF0aW9uMSgwJgYDVQQDDB9ZdWJpY28gVTJGIEVFIFNlcmlhbCAyMDE0ODA0Mzc5MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAETAZOKKrzwwAt0vCs9bDGCjmvATlCgCkn53Sp13iiRNQHa2HepLsy8Dm+h5K4wqkoKGuo16K1omdeUHSs8syPraOBlDCBkTATBgorBgEEAYLECg0BBAUEAwUEAjAQBgkrBgEEAYLECgwEAwIBBDAiBgkrBgEEAYLECgIEFTEuMy42LjEuNC4xLjQxNDgyLjEuNzATBgsrBgEEAYLlHAIBAQQEAwICJDAhBgsrBgEEAYLlHAEBBAQSBBCFIDQhSPlDVZvIilOEblCDMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFybB6BcC0kstjohJiA8Aczi2MQqkVWOUaLTtdrWyPcbSHfiqjjtn2J4lDxrCossqvmwrpAJ6vZ4rvHpv8dcJAFCA8Q02SaMWU/HgBjf3EZsowaxJqTPYsq86UmQG0+Y9BGuLZ1higWE1Pptpgumwkimo7q/H6Hvv0Da2FReEzAHYpwwrDfak+O+s3HEiKRRoqAprheNSunp1YXCnq6PCMho+gFbM1ULgx7D3eN/AQfMlhwa7vN7SoDRA93o6Gojdh54Mm2M5KuxX5NmNgfcfn7csvhXuDEw3J6YUE1Nd79bOBFAdSc1ZcQLBGaggIYQwy7p0R8gWh0T4AZEk+GHsMdoYXV0aERhdGFYxMRs74KtG1Rkd1kdAIsIdZ7D5tLstPOUdL/qaWmSXQO3QQAAAAKFIDQhSPlDVZvIilOEblCDAECp43L1YZ3opECrhpd//EKA6uCMmhEftV7woLtQndymMNoWu/l6CvmQnuYGWsaIeVnQ6QP9e2x36VBO79iavVyupQECAyYgASFYIMMwT+xzGRGxDx68988LHQ2WBrHQ0/ikpBffxxPtyQ92Ilggq9B/tvF9OQzKJddRibjoYmYfZtVk20wt7OKpz/a4FLU="),
+    ),
+    AssertionExample(
+      id =
+        ByteArray.fromBase64Url("qeNy9WGd6KRAq4aXf_xCgOrgjJoRH7Ve8KC7UJ3cpjDaFrv5egr5kJ7mBlrGiHlZ0OkD_Xtsd-lQTu_Ymr1crg"),
+      clientData = """{"type":"webauthn.get","challenge":"gJQG3mUBQv5rR7mwUuHbxQ","origin":"https://demo.yubico.com","crossOrigin":false"}""",
+      authDataBytes = ByteArray.fromBase64(
+        "xGzvgq0bVGR3WR0Aiwh1nsPm0uy085R0v+ppaZJdA7cBAAAABQ=="
+      ),
+      sig =
+        ByteArray.fromBase64("MEQCIEZeZWSy5CfVPMIGnU1Fi3+K+8ID6YTDxdckc9174ICeAiA1qRNIbPoo2tMSR1wFi5PTb6s+nZ2q9apv9NhnDbNZig=="),
+    ),
+  )
+
 }

From 683121155f54aaa18e67ba9e0900516273b703c2 Mon Sep 17 00:00:00 2001
From: Emil Lundberg <emil@yubico.com>
Date: Fri, 21 May 2021 02:01:19 +0200
Subject: [PATCH 2/2] Add YubiKey 5.4 FIPS to attestation metadata

---
 NEWS                                          |  4 ++
 .../src/main/resources/metadata.json          | 63 ++++++++++++++++++-
 2 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/NEWS b/NEWS
index 7f4ecf35a..87f98ee1b 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,10 @@
 * Added missing `<dependencyManagement>` declaration to
   `webauthn-server-attestation` and `webauthn-server-core` POMs.
 
+webauthn-server-attestation:
+
+* Added attestation metadata for YubiKey 5 FIPS series.
+
 
 == Version 1.9.0 ==
 
diff --git a/webauthn-server-attestation/src/main/resources/metadata.json b/webauthn-server-attestation/src/main/resources/metadata.json
index 248b47055..58254075d 100755
--- a/webauthn-server-attestation/src/main/resources/metadata.json
+++ b/webauthn-server-attestation/src/main/resources/metadata.json
@@ -1,6 +1,6 @@
 {
   "identifier": "2fb54029-7613-4f1d-94f1-fb876c14a6fe",
-  "version": 14,
+  "version": 15,
   "vendorInfo": {
     "url": "https://yubico.com",
     "imageUrl": "https://developers.yubico.com/U2F/Images/yubico.png",
@@ -241,6 +241,67 @@
           }
         }
       ]
+    },
+
+
+    {
+      "deviceId": "1.3.6.1.4.1.41482.1.7",
+      "displayName": "YubiKey 5/5C NFC FIPS",
+      "transports": 12,
+      "deviceUrl": "https://support.yubico.com/hc/en-us/articles/360021443340-YubiKey-5-NFC-FIPS",
+      "imageUrl": "https://developers.yubico.com/U2F/Images/YK5.png",
+      "selectors": [
+        {
+          "type": "x509Extension",
+          "parameters": {
+            "key": "1.3.6.1.4.1.45724.1.1.4",
+            "value": {
+              "type": "hex",
+              "value": "c1f9a0bc1dd2404ab27f8e29047a43fd"
+            }
+          }
+        }
+      ]
+    },
+
+    {
+      "deviceId": "1.3.6.1.4.1.41482.1.7",
+      "displayName": "YubiKey 5 FIPS series",
+      "transports": 4,
+      "deviceUrl": "https://support.yubico.com/hc/en-us/articles/360021467359-YubiKey-5C-FIPS",
+      "imageUrl": "https://developers.yubico.com/U2F/Images/YK5-series.png",
+      "selectors": [
+        {
+          "type": "x509Extension",
+          "parameters": {
+            "key": "1.3.6.1.4.1.45724.1.1.4",
+            "value": {
+              "type": "hex",
+              "value": "73bb0cd4e50249b89c6fb59445bf720b"
+            }
+          }
+        }
+      ]
+    },
+
+    {
+      "deviceId": "1.3.6.1.4.1.41482.1.7",
+      "displayName": "YubiKey 5Ci FIPS",
+      "transports": 20,
+      "deviceUrl": "https://support.yubico.com/hc/en-us/articles/360021443360-YubiKey-5Ci-FIPS",
+      "imageUrl": "https://developers.yubico.com/U2F/Images/YK5Ci.png",
+      "selectors": [
+        {
+          "type": "x509Extension",
+          "parameters": {
+            "key": "1.3.6.1.4.1.45724.1.1.4",
+            "value": {
+              "type": "hex",
+              "value": "8520342148f943559bc88a53846e5083"
+            }
+          }
+        }
+      ]
     }
   ]
 }