Skip to content

Commit 2481a44

Browse files
committed
Version 1.10.0
webauthn-server-attestation: - Added attestation metadata for YubiKey Bio.
2 parents 0f92fce + 2c79c90 commit 2481a44

File tree

14 files changed

+256
-213
lines changed

14 files changed

+256
-213
lines changed

NEWS

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
== Version 1.10.0 ==
2+
3+
webauthn-server-attestation:
4+
5+
* Added attestation metadata for YubiKey Bio.
6+
7+
18
== Version 1.9.1 ==
29

310
* Added missing `<dependencyManagement>` declaration to

README

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ Maven:
2525
<dependency>
2626
<groupId>com.yubico</groupId>
2727
<artifactId>webauthn-server-core</artifactId>
28-
<version>1.9.1</version>
28+
<version>1.10.0</version>
2929
<scope>compile</scope>
3030
</dependency>
3131
----------
3232

3333
Gradle:
3434

3535
----------
36-
compile 'com.yubico:webauthn-server-core:1.9.1'
36+
compile 'com.yubico:webauthn-server-core:1.10.0'
3737
----------
3838

3939
=== Semantic versioning
@@ -74,6 +74,8 @@ In addition to the main `webauthn-server-core` module, there are also:
7474
- Optionally integrates with a "metadata service" to verify
7575
https://www.w3.org/TR/webauthn/#sctn-attestation[authenticator attestations]
7676
and annotate responses with additional authenticator metadata
77+
- Reproducible builds: release signatures match fresh builds from source. See
78+
link:#Building[Building] below.
7779

7880

7981
=== Non-features
@@ -340,18 +342,25 @@ will have a plain `x.y.z` version number, while a build on any other commit will
340342
result in a version number containing the abbreviated commit hash.
341343

342344
Starting in version `1.4.0-RC2`, artifacts are built reproducibly. Fresh builds from
343-
tagged commits should therefore be verifiable by signatures from Maven Central:
345+
tagged commits should therefore be verifiable by signatures from Maven Central
346+
and GitHub releases:
344347

345348
```
346349
$ git checkout 1.4.0-RC2
347350
$ ./gradlew :webauthn-server-core:jar
351+
348352
$ wget https://repo1.maven.org/maven2/com/yubico/webauthn-server-core/1.4.0-RC2/webauthn-server-core-1.4.0-RC2.jar.asc
349353
$ gpg --verify webauthn-server-core-1.4.0-RC2.jar.asc webauthn-server-core/build/libs/webauthn-server-core-1.4.0-RC2.jar
354+
355+
$ wget https://github.com/Yubico/java-webauthn-server/releases/download/1.4.0-RC2/webauthn-server-core-1.4.0-RC2.jar.asc
356+
$ gpg --verify webauthn-server-core-1.4.0-RC2.jar.asc webauthn-server-core/build/libs/webauthn-server-core-1.4.0-RC2.jar
350357
```
351358

352359
Note that building with a different JDK may produce a different artifact. To
353360
ensure binary reproducibility, please build with the same JDK as specified in
354-
the release notes.
361+
the release notes. Reproducible builds also require building from a Git
362+
repository, since the build embeds version number and Git commit ID into the
363+
built artifacts.
355364

356365
Official Yubico software signing keys are listed on the
357366
https://developers.yubico.com/Software_Projects/Software_Signing.html[Yubico

build.gradle

Lines changed: 40 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ buildscript {
44
}
55
dependencies {
66
classpath 'com.cinnober.gradle:semver-git:2.5.0'
7-
classpath 'com.diffplug.spotless:spotless-plugin-gradle:5.12.5'
7+
classpath 'com.diffplug.spotless:spotless-plugin-gradle:5.14.1'
88
classpath 'io.github.cosmicsilence:gradle-scalafix:0.1.8'
99
}
1010
}
@@ -100,8 +100,7 @@ subprojects {
100100

101101
repositories {
102102
mavenLocal()
103-
104-
maven { url "https://repo.maven.apache.org/maven2" }
103+
mavenCentral()
105104
}
106105

107106
spotless {
@@ -220,7 +219,7 @@ subprojects { project ->
220219
}
221220
}
222221

223-
if (publishEnabled && project.hasProperty('publishMe') && project.publishMe) {
222+
if (project.hasProperty('publishMe') && project.publishMe) {
224223

225224
apply plugin: 'maven-publish'
226225
apply plugin: 'signing'
@@ -267,56 +266,59 @@ subprojects { project ->
267266
}
268267
}
269268

270-
signing {
271-
useGpgCmd()
272-
sign publishing.publications.jars
269+
if (publishEnabled) {
270+
signing {
271+
useGpgCmd()
272+
sign publishing.publications.jars
273+
}
273274
}
274275
}
276+
275277
}
276278

277279
// The root project has no sources, but the dependency platform also needs to be published as an artifact
278280
// See https://docs.gradle.org/current/userguide/java_platform_plugin.html
279281
// See https://github.com/Yubico/java-webauthn-server/issues/93#issuecomment-822806951
280-
if (publishEnabled) {
281-
apply plugin: 'maven-publish'
282-
apply plugin: 'signing'
283-
284-
publishing {
285-
publications {
286-
jars(MavenPublication) {
287-
from components.javaPlatform
288-
289-
pom {
290-
name = project.name
291-
description = project.description
292-
url = 'https://developers.yubico.com/java-webauthn-server/'
293-
294-
developers {
295-
developer {
296-
id = 'emil'
297-
name = 'Emil Lundberg'
298-
299-
}
282+
apply plugin: 'maven-publish'
283+
apply plugin: 'signing'
284+
285+
publishing {
286+
publications {
287+
jars(MavenPublication) {
288+
from components.javaPlatform
289+
290+
pom {
291+
name = project.name
292+
description = project.description
293+
url = 'https://developers.yubico.com/java-webauthn-server/'
294+
295+
developers {
296+
developer {
297+
id = 'emil'
298+
name = 'Emil Lundberg'
299+
300300
}
301+
}
301302

302-
licenses {
303-
license {
304-
name = 'BSD-license'
305-
comments = 'Revised 2-clause BSD license'
306-
}
303+
licenses {
304+
license {
305+
name = 'BSD-license'
306+
comments = 'Revised 2-clause BSD license'
307307
}
308+
}
308309

309-
scm {
310-
url = 'scm:git:git://github.com/Yubico/java-webauthn-server.git'
311-
connection = 'scm:git:git://github.com/Yubico/java-webauthn-server.git'
312-
developerConnection = 'scm:git:ssh://[email protected]/Yubico/java-webauthn-server.git'
313-
tag = 'HEAD'
314-
}
310+
scm {
311+
url = 'scm:git:git://github.com/Yubico/java-webauthn-server.git'
312+
connection = 'scm:git:git://github.com/Yubico/java-webauthn-server.git'
313+
developerConnection = 'scm:git:ssh://[email protected]/Yubico/java-webauthn-server.git'
314+
tag = 'HEAD'
315315
}
316316
}
317317
}
318318
}
319+
}
319320

321+
if (publishEnabled) {
320322
signing {
321323
useGpgCmd()
322324
sign publishing.publications.jars

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

Lines changed: 19 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": 15,
3+
"version": 16,
44
"vendorInfo": {
55
"url": "https://yubico.com",
66
"imageUrl": "https://developers.yubico.com/U2F/Images/yubico.png",
@@ -302,6 +302,24 @@
302302
}
303303
}
304304
]
305+
},
306+
307+
{
308+
"deviceId": "1.3.6.1.4.1.41482.1.9",
309+
"displayName": "YubiKey Bio",
310+
"transports": 4,
311+
"selectors": [
312+
{
313+
"type": "x509Extension",
314+
"parameters": {
315+
"key": "1.3.6.1.4.1.45724.1.1.4",
316+
"value": {
317+
"type": "hex",
318+
"value": "d8522d9f575b486688a9ba99fa02f35b"
319+
}
320+
}
321+
}
322+
]
305323
}
306324
]
307325
}

webauthn-server-attestation/src/test/scala/com/yubico/webauthn/attestation/DeviceIdentificationSpec.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,14 @@ class DeviceIdentificationSpec extends FunSpec with Matchers {
169169
Set(USB, LIGHTNING),
170170
)
171171
}
172+
173+
it("a YubiKey Bio.") {
174+
check(
175+
"YubiKey Bio",
176+
RealExamples.YubikeyBio_5_5_4,
177+
Set(USB),
178+
)
179+
}
172180
}
173181

174182
describe("fails to identify") {
@@ -293,6 +301,14 @@ class DeviceIdentificationSpec extends FunSpec with Matchers {
293301
Set(USB, LIGHTNING),
294302
)
295303
}
304+
305+
it("a YubiKey Bio.") {
306+
check(
307+
"YubiKey Bio",
308+
RealExamples.YubikeyBio_5_5_4,
309+
Set(USB),
310+
)
311+
}
296312
}
297313
}
298314

webauthn-server-attestation/src/test/scala/com/yubico/webauthn/attestation/StandardMetadataServiceSpec.scala

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424

2525
package com.yubico.webauthn.attestation
2626

27-
import com.fasterxml.jackson.databind.node.JsonNodeFactory
2827
import com.yubico.internal.util.JacksonCodecs
2928
import com.yubico.internal.util.scala.JavaConverters._
3029
import com.yubico.webauthn.TestAuthenticator
@@ -46,8 +45,6 @@ import scala.jdk.CollectionConverters._
4645
@RunWith(classOf[JUnitRunner])
4746
class StandardMetadataServiceSpec extends FunSpec with Matchers {
4847

49-
private def jsonFactory: JsonNodeFactory = JsonNodeFactory.instance
50-
5148
private val TRANSPORTS_EXT_OID = "1.3.6.1.4.1.45724.2.1.1"
5249

5350
private val ooidA = "1.3.6.1.4.1.41482.1.1"
@@ -109,10 +106,6 @@ class StandardMetadataServiceSpec extends FunSpec with Matchers {
109106
caCertAndKey = Some((caCert, caKey)),
110107
extensions = List((ooidB, false, new DEROctetString(Array[Byte]()))),
111108
)
112-
val (unknownCert, _) = TestAuthenticator.generateAttestationCertificate(
113-
name = new X500Name("CN=Unknown Cert"),
114-
extensions = List((ooidA, false, new DEROctetString(Array[Byte]()))),
115-
)
116109

117110
val metadataJson =
118111
s"""{

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

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -121,18 +121,18 @@ class RelyingPartyAssertionSpec
121121

122122
}
123123

124-
private def getUserHandleIfDefault(
124+
private def getUserHandleIfDefaultUsername(
125125
username: String,
126-
userHandle: ByteArray = Defaults.userHandle,
126+
userHandle: ByteArray,
127127
): Optional[ByteArray] =
128128
if (username == Defaults.username)
129129
Some(userHandle).asJava
130130
else
131131
???
132132

133-
private def getUsernameIfDefault(
133+
private def getUsernameIfDefaultUserHandle(
134134
userHandle: ByteArray,
135-
username: String = Defaults.username,
135+
username: String,
136136
): Optional[String] =
137137
if (userHandle == Defaults.userHandle)
138138
Some(username).asJava
@@ -242,10 +242,16 @@ class RelyingPartyAssertionSpec
242242
override def getCredentialIdsForUsername(username: String) = ???
243243
override def getUserHandleForUsername(username: String)
244244
: Optional[ByteArray] =
245-
getUserHandleIfDefault(username, userHandle = userHandleForUser)
245+
getUserHandleIfDefaultUsername(
246+
username,
247+
userHandle = userHandleForUser,
248+
)
246249
override def getUsernameForUserHandle(userHandle: ByteArray)
247250
: Optional[String] =
248-
getUsernameIfDefault(userHandle, username = usernameForUser)
251+
getUsernameIfDefaultUserHandle(
252+
userHandle,
253+
username = usernameForUser,
254+
)
249255
}
250256
)
251257
.preferredPubkeyParams(Nil.asJava)

0 commit comments

Comments
 (0)