Skip to content

Commit f8cbe35

Browse files
committed
Release 1.6.0
Security fixes: - Bumped Jackson dependency to version 2.9.10.1 which has patched CVE-2019-16942 `webauthn-server-core`: Bug fixes: - Fixed bug introduced in 1.4.0, which caused `RegistrationResult.attestationMetadata` to always be empty. `webauthn-server-attestation`: - New enum constant `Transport.LIGHTNING` - Fixed transports field of YubiKey NEO/NEO-n in `metadata.json`. - Added YubiKey 5Ci to `metadata.json`. - Most `deviceUrl` fields in `metadata.json` changed to point to stable addresses in Yubico knowledge base instead of dead redirects in store.
2 parents f8693e0 + 732fe22 commit f8cbe35

File tree

25 files changed

+996
-547
lines changed

25 files changed

+996
-547
lines changed

NEWS

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,26 @@
1+
== Version 1.6.0 ==
2+
3+
Security fixes:
4+
5+
- Bumped Jackson dependency to version 2.9.10.1 which has patched CVE-2019-16942
6+
7+
`webauthn-server-core`:
8+
9+
Bug fixes:
10+
11+
- Fixed bug introduced in 1.4.0, which caused
12+
`RegistrationResult.attestationMetadata` to always be empty.
13+
14+
15+
`webauthn-server-attestation`:
16+
17+
- New enum constant `Transport.LIGHTNING`
18+
- Fixed transports field of YubiKey NEO/NEO-n in `metadata.json`.
19+
- Added YubiKey 5Ci to `metadata.json`.
20+
- Most `deviceUrl` fields in `metadata.json` changed to point to stable
21+
addresses in Yubico knowledge base instead of dead redirects in store.
22+
23+
124
== Version 1.5.0 ==
225

326
Changes:

build.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ allprojects {
5151
Map<String, String> dependencyVersions = [
5252
'ch.qos.logback:logback-classic:1.2.3',
5353
'com.augustcellars.cose:cose-java:1.0.0',
54-
'com.fasterxml.jackson.core:jackson-databind:2.9.9.3',
55-
'com.fasterxml.jackson.dataformat:jackson-dataformat-cbor:2.9.9',
56-
'com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.9.9',
54+
'com.fasterxml.jackson.core:jackson-databind:2.9.10.1',
55+
'com.fasterxml.jackson.dataformat:jackson-dataformat-cbor:2.9.10',
56+
'com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.9.10',
5757
'com.google.guava:guava:19.0',
5858
'com.upokecenter:cbor:4.0.1',
5959
'javax.activation:activation:1.1.1',

webauthn-server-attestation/src/main/resources/metadata.json

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"identifier": "2fb54029-7613-4f1d-94f1-fb876c14a6fe",
3-
"version": 5,
3+
"version": 11,
44
"vendorInfo": {
55
"url": "https://yubico.com",
66
"imageUrl": "https://developers.yubico.com/U2F/Images/yubico.png",
@@ -14,7 +14,7 @@
1414
"deviceId": "1.3.6.1.4.1.41482.1.1",
1515
"displayName": "Security Key NFC by Yubico",
1616
"transports": 12,
17-
"deviceUrl": "https://www.yubico.com/product/security-key-nfc-by-yubico/",
17+
"deviceUrl": "https://support.yubico.com/support/solutions/articles/15000019469-security-key-nfc",
1818
"imageUrl": "https://developers.yubico.com/U2F/Images/SKY-NFC.png",
1919
"selectors": [
2020
{
@@ -34,7 +34,7 @@
3434
"deviceId": "1.3.6.1.4.1.41482.1.1",
3535
"displayName": "Security Key by Yubico",
3636
"transports": 4,
37-
"deviceUrl": "https://www.yubico.com/products/yubikey-hardware/fido-u2f-security-key/",
37+
"deviceUrl": "https://support.yubico.com/support/solutions/articles/15000006900-security-key-by-yubico",
3838
"imageUrl": "https://developers.yubico.com/U2F/Images/SKY.png",
3939
"selectors": [
4040
{
@@ -55,8 +55,8 @@
5555
{
5656
"deviceId": "1.3.6.1.4.1.41482.1.2",
5757
"displayName": "YubiKey NEO/NEO-n",
58-
"transports": 4,
59-
"deviceUrl": "https://www.yubico.com/products/yubikey-hardware/yubikey-neo/",
58+
"transports": 12,
59+
"deviceUrl": "https://support.yubico.com/support/solutions/articles/15000006494-yubikey-neo",
6060
"imageUrl": "https://developers.yubico.com/U2F/Images/NEO.png",
6161
"selectors": [
6262
{
@@ -100,7 +100,7 @@
100100
"deviceId": "1.3.6.1.4.1.41482.1.4",
101101
"displayName": "YubiKey Edge",
102102
"transports": 4,
103-
"deviceUrl": "https://www.yubico.com/products/yubikey-hardware/",
103+
"deviceUrl": "https://support.yubico.com/support/solutions/articles/15000006492-yubikey-edge",
104104
"imageUrl": "https://developers.yubico.com/U2F/Images/YKE.png",
105105
"selectors": [
106106
{
@@ -116,7 +116,7 @@
116116
"deviceId": "1.3.6.1.4.1.41482.1.5",
117117
"displayName": "YubiKey 4/YubiKey 4 Nano",
118118
"transports": 4,
119-
"deviceUrl": "https://www.yubico.com/products/yubikey-hardware/yubikey4/",
119+
"deviceUrl": "https://support.yubico.com/support/solutions/articles/15000006486-yubikey-4",
120120
"imageUrl": "https://developers.yubico.com/U2F/Images/YK4.png",
121121
"selectors": [
122122
{
@@ -132,7 +132,7 @@
132132
"deviceId": "1.3.6.1.4.1.41482.1.7",
133133
"displayName": "YubiKey 5 NFC",
134134
"transports": 12,
135-
"deviceUrl": "https://www.yubico.com/products/yubikey-5-overview/",
135+
"deviceUrl": "https://support.yubico.com/support/solutions/articles/15000014174--yubikey-5-nfc",
136136
"imageUrl": "https://developers.yubico.com/U2F/Images/YK5.png",
137137
"selectors": [
138138
{
@@ -151,7 +151,7 @@
151151
"deviceId": "1.3.6.1.4.1.41482.1.7",
152152
"displayName": "YubiKey 5 Series security key",
153153
"transports": 4,
154-
"deviceUrl": "https://www.yubico.com/products/yubikey-5-overview/",
154+
"deviceUrl": "https://support.yubico.com/support/solutions/articles/15000014180-yubikey-5c",
155155
"imageUrl": "https://developers.yubico.com/U2F/Images/YK5-series.png",
156156
"selectors": [
157157
{
@@ -165,6 +165,25 @@
165165
}
166166
}
167167
]
168+
},
169+
{
170+
"deviceId": "1.3.6.1.4.1.41482.1.7",
171+
"displayName": "YubiKey 5Ci",
172+
"transports": 20,
173+
"deviceUrl": "https://support.yubico.com/support/solutions/articles/15000027140-yubikey-5ci",
174+
"imageUrl": "https://developers.yubico.com/U2F/Images/YK5Ci.png",
175+
"selectors": [
176+
{
177+
"type": "x509Extension",
178+
"parameters": {
179+
"key": "1.3.6.1.4.1.45724.1.1.4",
180+
"value": {
181+
"type": "hex",
182+
"value": "c5ef55ffad9a4b9fb580adebafe026d0"
183+
}
184+
}
185+
}
186+
]
168187
}
169188
]
170189
}
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
// Copyright (c) 2018, Yubico AB
2+
// All rights reserved.
3+
//
4+
// Redistribution and use in source and binary forms, with or without
5+
// modification, are permitted provided that the following conditions are met:
6+
//
7+
// 1. Redistributions of source code must retain the above copyright notice, this
8+
// list of conditions and the following disclaimer.
9+
//
10+
// 2. Redistributions in binary form must reproduce the above copyright notice,
11+
// this list of conditions and the following disclaimer in the documentation
12+
// and/or other materials provided with the distribution.
13+
//
14+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16+
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17+
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
18+
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19+
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20+
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21+
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22+
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24+
25+
package com.yubico.webauthn.attestation
26+
27+
import java.util.Collections
28+
29+
import com.yubico.internal.util.CertificateParser
30+
import com.yubico.internal.util.JacksonCodecs
31+
import com.yubico.webauthn.attestation.resolver.SimpleAttestationResolver
32+
import com.yubico.webauthn.attestation.resolver.SimpleTrustResolver
33+
import com.yubico.webauthn.test.RealExamples
34+
import com.yubico.webauthn.FinishRegistrationOptions
35+
import com.yubico.webauthn.RelyingParty
36+
import com.yubico.webauthn.attestation.Transport.LIGHTNING
37+
import com.yubico.webauthn.attestation.Transport.NFC
38+
import com.yubico.webauthn.attestation.Transport.USB
39+
import com.yubico.webauthn.data.PublicKeyCredentialCreationOptions
40+
import com.yubico.webauthn.data.PublicKeyCredentialParameters
41+
import com.yubico.webauthn.test.Helpers
42+
import org.junit.runner.RunWith
43+
import org.scalatest.FunSpec
44+
import org.scalatest.Matchers
45+
import org.scalatest.junit.JUnitRunner
46+
47+
import scala.collection.JavaConverters._
48+
49+
50+
@RunWith(classOf[JUnitRunner])
51+
class DeviceIdentificationSpec extends FunSpec with Matchers {
52+
53+
def metadataService(metadataJson: String): StandardMetadataService = {
54+
val metadata = Collections.singleton(JacksonCodecs.json().readValue(metadataJson, classOf[MetadataObject]))
55+
new StandardMetadataService(
56+
new SimpleAttestationResolver(metadata, SimpleTrustResolver.fromMetadata(metadata))
57+
)
58+
}
59+
60+
describe("A RelyingParty with the default StandardMetadataService") {
61+
62+
describe("correctly identifies") {
63+
def check(expectedName: String, testData: RealExamples.Example, transports: Set[Transport]) {
64+
val rp = RelyingParty.builder()
65+
.identity(testData.rp)
66+
.credentialRepository(Helpers.CredentialRepository.empty)
67+
.metadataService(new StandardMetadataService())
68+
.build()
69+
70+
val result = rp.finishRegistration(FinishRegistrationOptions.builder()
71+
.request(PublicKeyCredentialCreationOptions.builder()
72+
.rp(testData.rp)
73+
.user(testData.user)
74+
.challenge(testData.attestation.challenge)
75+
.pubKeyCredParams(List(PublicKeyCredentialParameters.ES256).asJava)
76+
.build())
77+
.response(testData.attestation.credential)
78+
.build());
79+
80+
result.isAttestationTrusted should be (true)
81+
result.getAttestationMetadata.isPresent should be (true)
82+
result.getAttestationMetadata.get.getDeviceProperties.isPresent should be (true)
83+
result.getAttestationMetadata.get.getDeviceProperties.get().get("displayName") should equal (expectedName)
84+
result.getAttestationMetadata.get.getTransports.isPresent should be (true)
85+
result.getAttestationMetadata.get.getTransports.get.asScala should equal (transports)
86+
}
87+
88+
it("a YubiKey NEO.") {
89+
check("YubiKey NEO/NEO-n", RealExamples.YubiKeyNeo, Set(USB, NFC))
90+
}
91+
it("a YubiKey 4.") {
92+
check("YubiKey 4/YubiKey 4 Nano", RealExamples.YubiKey4, Set(USB))
93+
}
94+
it("a YubiKey 5 NFC.") {
95+
check("YubiKey 5 NFC", RealExamples.YubiKey5, Set(USB, NFC))
96+
}
97+
it("a YubiKey 5 Nano.") {
98+
check("YubiKey 5 Series security key", RealExamples.YubiKey5Nano, Set(USB))
99+
}
100+
it("a YubiKey 5Ci.") {
101+
check("YubiKey 5Ci", RealExamples.YubiKey5Ci, Set(USB, LIGHTNING))
102+
}
103+
it("a Security Key by Yubico.") {
104+
check("Security Key by Yubico", RealExamples.SecurityKey, Set(USB))
105+
}
106+
it("a Security Key 2 by Yubico.") {
107+
check("Security Key by Yubico", RealExamples.SecurityKey2, Set(USB))
108+
}
109+
it("a Security Key NFC by Yubico.") {
110+
check("Security Key NFC by Yubico", RealExamples.SecurityKeyNfc, Set(USB, NFC))
111+
}
112+
}
113+
}
114+
115+
describe("The default AttestationResolver") {
116+
describe("successfully identifies") {
117+
def check(expectedName: String, testData: RealExamples.Example, transports: Set[Transport]) {
118+
val cert = CertificateParser.parseDer(testData.attestationCert.getBytes)
119+
val resolved = StandardMetadataService.createDefaultAttestationResolver().resolve(cert)
120+
resolved.isPresent should be (true)
121+
resolved.get.getDeviceProperties.isPresent should be (true)
122+
resolved.get.getDeviceProperties.get.get("displayName") should equal (expectedName)
123+
resolved.get.getTransports.isPresent should be (true)
124+
resolved.get.getTransports.get.asScala should equal (transports)
125+
}
126+
127+
it("a YubiKey NEO.") {
128+
check("YubiKey NEO/NEO-n", RealExamples.YubiKeyNeo, Set(USB, NFC))
129+
}
130+
it("a YubiKey 4.") {
131+
check("YubiKey 4/YubiKey 4 Nano", RealExamples.YubiKey4, Set(USB))
132+
}
133+
it("a YubiKey 5 NFC.") {
134+
check("YubiKey 5 NFC", RealExamples.YubiKey5, Set(USB, NFC))
135+
}
136+
it("a YubiKey 5 Nano.") {
137+
check("YubiKey 5 Series security key", RealExamples.YubiKey5Nano, Set(USB))
138+
}
139+
it("a YubiKey 5Ci.") {
140+
check("YubiKey 5Ci", RealExamples.YubiKey5Ci, Set(USB, LIGHTNING))
141+
}
142+
it("a Security Key by Yubico.") {
143+
check("Security Key by Yubico", RealExamples.SecurityKey, Set(USB))
144+
}
145+
it("a Security Key 2 by Yubico.") {
146+
check("Security Key by Yubico", RealExamples.SecurityKey2, Set(USB))
147+
}
148+
it("a Security Key NFC by Yubico.") {
149+
check("Security Key NFC by Yubico", RealExamples.SecurityKeyNfc, Set(USB, NFC))
150+
}
151+
}
152+
}
153+
154+
}

webauthn-server-core/src/main/java/com/yubico/webauthn/RegistrationResult.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,8 @@ public class RegistrationResult {
112112
* @see <a href="https://www.w3.org/TR/2019/PR-webauthn-20190117/#sctn-attestation">§6.4. Attestation</a>
113113
* @see com.yubico.webauthn.RelyingParty.RelyingPartyBuilder#metadataService(Optional)
114114
*/
115-
@Builder.Default
116115
@Builder.ObtainVia(method = "getAttestationMetadata")
117-
private final Attestation attestationMetadata = null;
116+
private final Attestation attestationMetadata;
118117

119118
@JsonCreator
120119
private RegistrationResult(

webauthn-server-core/src/main/java/com/yubico/webauthn/attestation/Transport.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,12 @@ public enum Transport {
5050
/**
5151
* The authenticator supports communication via Near Field Communication (NFC).
5252
*/
53-
NFC(8);
53+
NFC(8),
54+
55+
/**
56+
* The authenticator supports communication via Lightning.
57+
*/
58+
LIGHTNING(16);
5459

5560
private final int bitpos;
5661

0 commit comments

Comments
 (0)