Skip to content

Commit 74ff8c6

Browse files
committed
Release 1.6.3
webauthn-server-attestation: - Added new YubiKey AAGUIDs to metadata.json webauthn-server-core: - Bumped Jackson dependency to version 2.11.0 in response to CVEs: - CVE-2020-9546 - CVE-2020-10672 - CVE-2020-10969 - CVE-2020-11620 - Fixed incorrect JavaDoc on AssertionResult.isSignatureCounterValid(): it will also return true if both counters are zero.
2 parents bc94105 + 929d26d commit 74ff8c6

File tree

13 files changed

+117
-63
lines changed

13 files changed

+117
-63
lines changed

.github/workflows/scan.yml

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ on:
99
env:
1010
SCAN_IMG:
1111
yes-docker-local.artifactory.in.yubico.org/static-code-analysis/java:v1
12+
SECRET: ${{ secrets.ARTIFACTORY_READER_TOKEN }}
1213

1314
jobs:
1415
build:
@@ -17,17 +18,17 @@ jobs:
1718
steps:
1819
- uses: actions/checkout@master
1920

20-
- name: Prep scan
21-
run: |
22-
docker login yes-docker-local.artifactory.in.yubico.org/ \
23-
-u svc-static-code-analysis-reader \
24-
-p ${{ secrets.ARTIFACTORY_READER_TOKEN }}
25-
docker pull ${SCAN_IMG}
26-
2721
- name: Scan and fail on warnings
2822
run: |
29-
docker run -v${PWD}:/k \
30-
-e PROJECT_NAME=${GITHUB_REPOSITORY#Yubico/} -t ${SCAN_IMG}
23+
if [ "${SECRET}" != "" ]; then
24+
docker login yes-docker-local.artifactory.in.yubico.org/ \
25+
-u svc-static-code-analysis-reader -p ${SECRET}
26+
docker pull ${SCAN_IMG}
27+
docker run -v${PWD}:/k \
28+
-e PROJECT_NAME=${GITHUB_REPOSITORY#Yubico/} -t ${SCAN_IMG}
29+
else
30+
echo "No docker registry credentials, not scanning"
31+
fi
3132
3233
- uses: actions/upload-artifact@master
3334
if: failure()

NEWS

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
== Version 1.6.3 ==
2+
3+
webauthn-server-attestation:
4+
5+
- Added new YubiKey AAGUIDs to metadata.json
6+
7+
8+
webauthn-server-core:
9+
10+
- Bumped Jackson dependency to version 2.11.0 in response to CVEs:
11+
- CVE-2020-9546
12+
- CVE-2020-10672
13+
- CVE-2020-10969
14+
- CVE-2020-11620
15+
- Fixed incorrect JavaDoc on AssertionResult.isSignatureCounterValid(): it will
16+
also return true if both counters are zero.
17+
18+
119
== Version 1.6.2 ==
220

321
- Fixed dependencies missing from release POM metadata

README

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -59,20 +59,6 @@ and other higher level concepts can make use of this authentication mechanism,
5959
but the authentication mechanism alone does not make a security system.
6060

6161

62-
== Known issues
63-
64-
- In the link:webauthn-server-demo[example app], authentication does not work in
65-
Chrome as of version 70. This is due to a
66-
link:https://bugs.chromium.org/p/chromium/issues/detail?id=847878[bug in
67-
Chrome] which will not be worked around here. To work around this in
68-
application code, you can omit the
69-
link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/latest/com/yubico/webauthn/data/AuthenticatorAssertionResponse.AuthenticatorAssertionResponseBuilder.html#userHandle-java.util.Optional[`userHandle`]
70-
when constructing an
71-
link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/latest/com/yubico/webauthn/data/AuthenticatorAssertionResponse.html[`AuthenticatorAssertionResponse`]
72-
value if the `userHandle` is empty. See
73-
https://github.com/Yubico/java-webauthn-server/issues/12 .
74-
75-
7662
== Documentation
7763

7864
See the

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.10.3',
55-
'com.fasterxml.jackson.dataformat:jackson-dataformat-cbor:2.9.10',
56-
'com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.9.10',
54+
'com.fasterxml.jackson.core:jackson-databind:2.11.0',
55+
'com.fasterxml.jackson.dataformat:jackson-dataformat-cbor:2.11.0',
56+
'com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.11.0',
5757
'com.google.guava:guava:19.0',
5858
'com.upokecenter:cbor:4.0.1',
5959
'javax.activation:activation:1.1.1',

gradle.properties

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Required for publishing to Sonatype Nexus
2+
# See https://issues.sonatype.org/browse/OSSRH-54054
3+
# See https://docs.gradle.org/6.0.1/release-notes.html#publication-of-sha256-and-sha512-checksums
4+
systemProp.org.gradle.internal.publish.checksums.insecure=true

webauthn-server-attestation/src/main/java/com/yubico/webauthn/attestation/MetadataObject.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@ public final class MetadataObject {
5454

5555
private static final TypeReference<Map<String, String>> MAP_STRING_STRING_TYPE = new TypeReference<Map<String, String>>() {
5656
};
57-
private static final TypeReference LIST_STRING_TYPE = new TypeReference<List<String>>() {
57+
private static final TypeReference<List<String>> LIST_STRING_TYPE = new TypeReference<List<String>>() {
5858
};
59-
private static final TypeReference LIST_JSONNODE_TYPE = new TypeReference<List<JsonNode>>() {
59+
private static final TypeReference<List<JsonNode>> LIST_JSONNODE_TYPE = new TypeReference<List<JsonNode>>() {
6060
};
6161

6262
private final transient JsonNode data;

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

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"identifier": "2fb54029-7613-4f1d-94f1-fb876c14a6fe",
3-
"version": 11,
3+
"version": 12,
44
"vendorInfo": {
55
"url": "https://yubico.com",
66
"imageUrl": "https://developers.yubico.com/U2F/Images/yubico.png",
@@ -26,6 +26,16 @@
2626
"value": "6d44ba9bf6ec2e49b9300c8fe920cb73"
2727
}
2828
}
29+
},
30+
{
31+
"type": "x509Extension",
32+
"parameters": {
33+
"key": "1.3.6.1.4.1.45724.1.1.4",
34+
"value": {
35+
"type": "hex",
36+
"value": "149a20218ef6413396b881f8d5b7f1f5"
37+
}
38+
}
2939
}
3040
]
3141
},
@@ -49,6 +59,16 @@
4959
"value": "1.3.6.1.4.1.41482.1.1",
5060
"key": "1.3.6.1.4.1.41482.2"
5161
}
62+
},
63+
{
64+
"type": "x509Extension",
65+
"parameters": {
66+
"key": "1.3.6.1.4.1.45724.1.1.4",
67+
"value": {
68+
"type": "hex",
69+
"value": "b92c3f9ac0144056887f140a2501163b"
70+
}
71+
}
5272
}
5373
]
5474
},
@@ -144,6 +164,16 @@
144164
"value": "fa2b99dc9e3942578f924a30d23c4118"
145165
}
146166
}
167+
},
168+
{
169+
"type": "x509Extension",
170+
"parameters": {
171+
"key": "1.3.6.1.4.1.45724.1.1.4",
172+
"value": {
173+
"type": "hex",
174+
"value": "2fc0579f811347eab116bb5a8db9202a"
175+
}
176+
}
147177
}
148178
]
149179
},
@@ -163,6 +193,16 @@
163193
"value": "cb69481e8ff7403993ec0a2729a154a8"
164194
}
165195
}
196+
},
197+
{
198+
"type": "x509Extension",
199+
"parameters": {
200+
"key": "1.3.6.1.4.1.45724.1.1.4",
201+
"value": {
202+
"type": "hex",
203+
"value": "ee882879721c491397753dfcce97072a"
204+
}
205+
}
166206
}
167207
]
168208
},

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,13 @@ public class AssertionResult {
9191
private final long signatureCount;
9292

9393
/**
94-
* <code>true</code> if and only if the {@link AuthenticatorData#getSignatureCounter() signature counter value}
95-
* in the assertion was strictly greater than {@link RegisteredCredential#getSignatureCount() the stored one}.
94+
* <code>true</code> if and only if at least one of the following is true:
95+
* <ul>
96+
* <li>The {@link AuthenticatorData#getSignatureCounter() signature counter value} in the assertion was strictly
97+
* greater than {@link RegisteredCredential#getSignatureCount() the stored one}.</li>
98+
* <li>The {@link AuthenticatorData#getSignatureCounter() signature counter value} in the assertion and
99+
* {@link RegisteredCredential#getSignatureCount() the stored one} were both zero.</li>
100+
* </ul>
96101
*
97102
* @see <a href="https://www.w3.org/TR/2019/PR-webauthn-20190117/#sec-authenticator-data">§6.1. Authenticator
98103
* Data</a>

webauthn-server-core/src/test/scala/com/yubico/scalacheck/gen/JacksonGenerators.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ object JacksonGenerators {
5050
} yield {
5151
val o = jsonFactory.objectNode()
5252
for { (name, value) <- names.zip(values) } {
53-
o.set(name, value)
53+
o.set[ObjectNode](name, value)
5454
}
5555
o
5656
}

webauthn-server-core/src/test/scala/com/yubico/webauthn/RegistrationTestData.scala

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ object RegistrationTestData {
128128
)
129129

130130
object AndroidKey {
131-
val BasicAttestation: RegistrationTestData = Packed.SelfAttestation.editAttestationObject("fmt", "android-key")
131+
val BasicAttestation: RegistrationTestData = Packed.SelfAttestation.setAttestationStatementFormat("android-key")
132132
}
133133
object AndroidSafetynet {
134134
val RealExample: RegistrationTestData = new RegistrationTestData(
@@ -254,7 +254,7 @@ object RegistrationTestData {
254254
) { override def regenerate() = TestAuthenticator.createSelfAttestedCredential(AttestationMaker.packed(_), keyAlgorithm = COSEAlgorithmIdentifier.RS1) }
255255
}
256256
object Tpm {
257-
val PrivacyCa: RegistrationTestData = Packed.BasicAttestation.editAttestationObject("fmt", "tpm")
257+
val PrivacyCa: RegistrationTestData = Packed.BasicAttestation.setAttestationStatementFormat("tpm")
258258
}
259259
}
260260

@@ -309,14 +309,14 @@ case class RegistrationTestData(
309309
.map(x5c => x5c.elements().asScala.toList.last)
310310
.map(node => CertificateParser.parseDer(node.binaryValue()))
311311

312-
def editClientData[A <: JsonNode](updater: ObjectNode => A): RegistrationTestData = copy(
312+
def editClientData(updater: ObjectNode => JsonNode): RegistrationTestData = copy(
313313
clientDataJson = JacksonCodecs.json.writeValueAsString(
314314
updater(JacksonCodecs.json.readTree(clientDataJson).asInstanceOf[ObjectNode])
315315
)
316316
)
317317

318-
def editClientData[A <: JsonNode](name: String, value: A): RegistrationTestData = editClientData { clientData: ObjectNode =>
319-
clientData.set(name, value)
318+
def editClientData(name: String, value: JsonNode): RegistrationTestData = editClientData { clientData: ObjectNode =>
319+
clientData.set[ObjectNode](name, value)
320320
}
321321
def editClientData(name: String, value: String): RegistrationTestData = editClientData(name, RegistrationTestData.jsonFactory.textNode(value))
322322
def responseChallenge: ByteArray = clientData.getChallenge
@@ -327,13 +327,13 @@ case class RegistrationTestData(
327327
RegistrationTestData.jsonFactory.textNode(value.getBase64Url)
328328
)
329329

330-
def editAttestationObject[A <: JsonNode](name: String, value: A): RegistrationTestData = copy(
330+
def editAttestationObject(name: String, value: JsonNode): RegistrationTestData = copy(
331331
attestationObject = new ByteArray(JacksonCodecs.cbor.writeValueAsBytes(
332332
JacksonCodecs.cbor.readTree(attestationObject.getBytes).asInstanceOf[ObjectNode]
333333
.set(name, value)
334334
))
335335
)
336-
def editAttestationObject[A <: JsonNode](name: String, updater: JsonNode => A): RegistrationTestData = {
336+
def updateAttestationObject(name: String, updater: JsonNode => JsonNode): RegistrationTestData = {
337337
val attObj = JacksonCodecs.cbor.readTree(attestationObject.getBytes)
338338
copy(
339339
attestationObject = new ByteArray(JacksonCodecs.cbor.writeValueAsBytes(
@@ -344,8 +344,8 @@ case class RegistrationTestData(
344344
)
345345
}
346346

347-
def editAttestationObject(name: String, value: String): RegistrationTestData =
348-
editAttestationObject(name, RegistrationTestData.jsonFactory.textNode(value))
347+
def setAttestationStatementFormat(value: String): RegistrationTestData =
348+
editAttestationObject("fmt", RegistrationTestData.jsonFactory.textNode(value))
349349

350350
def editAuthenticatorData(updater: ByteArray => ByteArray): RegistrationTestData = {
351351
val attObj: ObjectNode = JacksonCodecs.cbor.readTree(attestationObject.getBytes).asInstanceOf[ObjectNode]

0 commit comments

Comments
 (0)