Skip to content

Commit dd85090

Browse files
committed
Release 0.4.0
Breaking changes: - Field `StartRegistrationOptions.requireResidentKey: boolean` replaced with field `authenticatorSelection: Optional<AuthenticatorSelectionCriteria>`
2 parents 536bb84 + 01f5295 commit dd85090

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+397
-630
lines changed

NEWS

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
== Version 0.4.0 ==
2+
3+
Breaking changes:
4+
5+
* Field `StartRegistrationOptions.requireResidentKey: boolean` replaced with
6+
field `authenticatorSelection: Optional<AuthenticatorSelectionCriteria>`
7+
8+
19
== Version 0.3.0 ==
210

311
* Major API overhaul; public API changes include but are not limited to:
@@ -25,10 +33,6 @@
2533
failures
2634
** Class `MetadataResolver` replaced with interface
2735
** Constructor `CollectedClientData(JsonNode)` deleted
28-
** Type of fields `StartAssertionOptions.extensions`,
29-
`StartRegistrationOptions.extensions` and
30-
`PublicKeyCredential.clientExtensionOutputs` narrowed from `JsonNode` to
31-
`ObjectNode`
3236
** Parameters `StartRegistrationOptions.excludeCredentials` and
3337
`StartAssertionOptions.allowCredentials` deleted; they are now discovered
3438
automatically from the `CredentialRepository`. If custom control over

README

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
== java-webauthn-server
22

33
_Note: This is a work in progress. The https://www.w3.org/TR/webauthn/[Web
4-
Authentication standard] is not yet finished, and any part of this project may
5-
change at any time._
4+
Authentication standard] is not yet finished, and additional pre-1.0 releases of
5+
this library may introduce breaking API changes._
66

77
image:https://travis-ci.org/Yubico/java-webauthn-server.svg?branch=master["Build Status", link="https://travis-ci.org/Yubico/java-webauthn-server"]
88
image:https://coveralls.io/repos/github/Yubico/java-webauthn-server/badge.svg["Coverage Status", link="https://coveralls.io/github/Yubico/java-webauthn-server"]
@@ -18,3 +18,39 @@ authenticators and authenticating registered authenticators.
1818

1919
See link:webauthn-server-demo[`webauthn-server-demo`] for a complete demo
2020
server, which stores authenticator registrations temporarily in memory.
21+
22+
23+
=== Building
24+
25+
Use the included
26+
https://docs.gradle.org/current/userguide/gradle_wrapper.html[Gradle wrapper] to
27+
build the `.jar` artifact:
28+
29+
```
30+
$ ./gradlew :webauthn-server-core:jar
31+
```
32+
33+
The output is built in the `webauthn-server-core/build/libs/` directory, and the
34+
version is derived from the most recent Git tag. Builds done on a tagged commit
35+
will have a plain `x.y.z` version number, while a build on any other commit will
36+
result in a version number containing the abbreviated commit hash.
37+
38+
Although the `.jar` artifact of this project can be used in JDK version 8 or
39+
later, the project as a whole currently builds only in JDK 8. This is because
40+
most tests are written in Scala, which
41+
https://docs.scala-lang.org/overviews/jdk-compatibility/overview.html#jdk-9\--up-compatibility-notes[currently
42+
only supports JDK 8]. Therefore compiling the tests can currently only be done
43+
in JDK 8, and so `./gradlew build` and similar tasks will fail in JDKs other
44+
than 8.
45+
46+
To run the tests (requires JDK 8):
47+
48+
```
49+
$ ./gradlew check
50+
```
51+
52+
To run the http://pitest.org/[PIT mutation tests] (requires JDK 8):
53+
54+
```
55+
$ ./gradlew pitest
56+
```

build.gradle

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ buildscript {
44
}
55
dependencies {
66
configurations.maybeCreate('pitest')
7-
classpath 'com.cinnober.gradle:semver-git:2.3.1'
7+
classpath 'com.cinnober.gradle:semver-git:2.4.0'
88
classpath 'info.solidsoft.gradle.pitest:gradle-pitest-plugin:1.3.0'
99
pitest 'org.pitest:pitest-command-line:1.4.2' // Transitive dependency from pitest plugin
1010
}
@@ -15,8 +15,11 @@ plugins {
1515
id 'net.researchgate.release' version '2.4.0'
1616
}
1717

18+
project.ext.isCiBuild = System.env.CI == 'true'
1819

19-
project.ext.publishEnabled = System.env.CI != 'true' && project.hasProperty('ossrhUsername')
20+
project.ext.publishEnabled = !isCiBuild &&
21+
project.hasProperty('yubicoPublish') && project.yubicoPublish &&
22+
project.hasProperty('ossrhUsername') && project.hasProperty('ossrhPassword')
2023

2124
if (publishEnabled) {
2225
nexusStaging {
@@ -31,22 +34,13 @@ task wrapper(type: Wrapper) {
3134
}
3235

3336
allprojects {
34-
ext.snapshotSuffix = "<count>.g<sha>-SNAPSHOT"
37+
ext.snapshotSuffix = "<count>.g<sha>-SNAPSHOT<dirty>"
38+
ext.dirtyMarker = "-DIRTY"
3539

3640
apply plugin: 'com.cinnober.gradle.semver-git'
3741
apply plugin: 'java'
38-
apply plugin: 'maven'
39-
apply plugin: 'signing'
4042
apply plugin: 'idea'
4143

42-
if (publishEnabled) {
43-
signing {
44-
useGpgCmd()
45-
sign configurations.archives
46-
}
47-
signArchives.dependsOn check
48-
}
49-
5044
group = 'com.yubico'
5145

5246
sourceCompatibility = 1.8
@@ -67,6 +61,10 @@ allprojects {
6761

6862
test {
6963
failFast = true
64+
65+
testLogging {
66+
showStandardStreams = isCiBuild
67+
}
7068
}
7169
}
7270

@@ -101,7 +99,17 @@ subprojects {
10199

102100
}
103101

104-
if (publishEnabled) {
102+
if (publishEnabled && project.hasProperty('publishMe') && project.publishMe) {
103+
104+
apply plugin: 'maven'
105+
apply plugin: 'signing'
106+
107+
signing {
108+
useGpgCmd()
109+
sign configurations.archives
110+
}
111+
signArchives.dependsOn check
112+
105113
uploadArchives {
106114
repositories {
107115
mavenDeployer {

webauthn-server-attestation/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ description = 'Yubico WebAuthn attestation subsystem'
22

33
apply plugin: 'java'
44

5+
project.ext.publishMe = true
6+
57
dependencies {
68

79
compile(

webauthn-server-core/README

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
= Web Authentication server library
2+
3+
Implementation of a Web Authentication Relying Party (RP).
4+
5+
6+
== Running
7+
8+
An example app is included in the
9+
link:../webauthn-server-demo[`webauthn-server-demo`] directory. See
10+
link:../webauthn-server-demo/README[its README] for instructions on how to run
11+
it.
12+
13+
14+
== Unimplemented features
15+
16+
* https://www.w3.org/TR/webauthn/#ecdaa[ECDAA] attestation type
17+
* Attestation statement formats:
18+
** https://www.w3.org/TR/webauthn/#tpm-attestation[`tpm`]
19+
** https://www.w3.org/TR/webauthn/#android-key-attestation[`android-key`]
20+
** https://www.w3.org/TR/webauthn/#android-safetynet-attestation[`android-safetynet`]
21+
* Extensions:
22+
** https://www.w3.org/TR/webauthn/#sctn-simple-txauth-extension[`txAuthSimple`]
23+
** https://www.w3.org/TR/webauthn/#sctn-generic-txauth-extension[`txAuthGeneric`]
24+
** https://www.w3.org/TR/webauthn/#sctn-authenticator-selection-extension[`authnSel`]
25+
** https://www.w3.org/TR/webauthn/#sctn-supported-extensions-extension[`exts`]
26+
** https://www.w3.org/TR/webauthn/#sctn-uvi-extension[`uvi`]
27+
** https://www.w3.org/TR/webauthn/#sctn-location-extension[`loc`]
28+
** https://www.w3.org/TR/webauthn/#sctn-uvm-extension[`uvm`]
29+
** https://www.w3.org/TR/webauthn/#sctn-authenticator-biometric-criteria-extension[`biometricPerfBounds`]

webauthn-server-core/README.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
README

webauthn-server-core/README.md

Lines changed: 0 additions & 33 deletions
This file was deleted.

webauthn-server-core/build.gradle

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
1-
import java.nio.file.Paths
2-
31
apply plugin: 'info.solidsoft.pitest'
42

53
description = 'WebAuthn core API'
64

75
apply plugin: 'scala'
86

9-
configurations {
10-
scalaRepl { extendsFrom testRuntime }
11-
}
7+
project.ext.publishMe = true
128

139
dependencies {
1410

@@ -31,11 +27,6 @@ dependencies {
3127
'org.scalacheck:scalacheck_2.11:1.13.5',
3228
)
3329

34-
scalaRepl(
35-
'org.scala-lang:scala-compiler:2.11.3',
36-
jar.outputs.files,
37-
)
38-
3930
}
4031

4132

@@ -68,17 +59,3 @@ pitest {
6859
]
6960
}
7061

71-
def scalaReplDistDir = file(Paths.get(project.distsDir.path, 'scala-repl'))
72-
task scalaReplClasspath(type: Sync) {
73-
from configurations.scalaRepl
74-
destinationDir = file(Paths.get(scalaReplDistDir.path, 'lib'))
75-
}
76-
77-
task makeScalaReplScripts(type: CreateStartScripts) {
78-
inputs.files tasks.scalaReplClasspath.outputs
79-
80-
applicationName = 'scala-repl'
81-
classpath = configurations.scalaRepl
82-
mainClassName = "scala.tools.nsc.MainGenericRunner"
83-
outputDir = file(Paths.get(scalaReplDistDir.path, 'bin'))
84-
}

webauthn-server-core/src/main/java/com/yubico/internal/util/WebAuthnCodecs.java

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.fasterxml.jackson.core.Base64Variants;
77
import com.fasterxml.jackson.databind.DeserializationFeature;
88
import com.fasterxml.jackson.databind.ObjectMapper;
9+
import com.fasterxml.jackson.databind.SerializationFeature;
910
import com.fasterxml.jackson.databind.node.ObjectNode;
1011
import com.fasterxml.jackson.dataformat.cbor.CBORFactory;
1112
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
@@ -28,6 +29,7 @@ public static ObjectMapper cbor() {
2829
public static ObjectMapper json() {
2930
return new ObjectMapper()
3031
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true)
32+
.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
3133
.setSerializationInclusion(Include.NON_ABSENT)
3234
.setBase64Variant(Base64Variants.MODIFIED_FOR_URL)
3335
.registerModule(new Jdk8Module())
@@ -84,7 +86,7 @@ public static ByteArray rawEcdaKeyToCose(ByteArray key) {
8486
Map<Long, Object> coseKey = new HashMap<>();
8587

8688
coseKey.put(1L, 2L); // Key type: EC
87-
coseKey.put(3L, javaAlgorithmNameToCoseAlgorithmIdentifier("ES256").getId());
89+
coseKey.put(3L, COSEAlgorithmIdentifier.ES256.getId());
8890
coseKey.put(-1L, 1L); // Curve: P-256
8991
coseKey.put(-2L, Arrays.copyOfRange(keyBytes, start, start + 32)); // x
9092
coseKey.put(-3L, Arrays.copyOfRange(keyBytes, start + 32, start + 64)); // y
@@ -100,17 +102,4 @@ public static ECPublicKey importCoseP256PublicKey(ByteArray key) throws CoseExce
100102
return new COSE.ECPublicKey(new OneKey(CBORObject.DecodeFromBytes(key.getBytes())));
101103
}
102104

103-
public static COSEAlgorithmIdentifier javaAlgorithmNameToCoseAlgorithmIdentifier(String alg) {
104-
switch (alg) {
105-
case "ECDSA":
106-
case "ES256":
107-
return COSEAlgorithmIdentifier.ES256;
108-
109-
case "RS256":
110-
return COSEAlgorithmIdentifier.RS256;
111-
}
112-
113-
throw new IllegalArgumentException("Unknown algorithm: " + alg);
114-
}
115-
116105
}

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

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import com.yubico.webauthn.data.AttestationConveyancePreference;
77
import com.yubico.webauthn.data.AuthenticatorAssertionResponse;
88
import com.yubico.webauthn.data.AuthenticatorAttestationResponse;
9-
import com.yubico.webauthn.data.AuthenticatorSelectionCriteria;
109
import com.yubico.webauthn.data.ByteArray;
1110
import com.yubico.webauthn.data.ClientAssertionExtensionOutputs;
1211
import com.yubico.webauthn.data.ClientRegistrationExtensionOutputs;
@@ -68,11 +67,7 @@ public PublicKeyCredentialCreationOptions startRegistration(StartRegistrationOpt
6867
.excludeCredentials(
6968
Optional.of(credentialRepository.getCredentialIdsForUsername(startRegistrationOptions.getUser().getName()))
7069
)
71-
.authenticatorSelection(Optional.of(
72-
AuthenticatorSelectionCriteria.builder()
73-
.requireResidentKey(startRegistrationOptions.isRequireResidentKey())
74-
.build()
75-
))
70+
.authenticatorSelection(startRegistrationOptions.getAuthenticatorSelection())
7671
.attestation(attestationConveyancePreference.orElse(AttestationConveyancePreference.DEFAULT))
7772
.extensions(startRegistrationOptions.getExtensions())
7873
.build();

0 commit comments

Comments
 (0)