Skip to content

Commit

Permalink
Release 0.4.0
Browse files Browse the repository at this point in the history
Breaking changes:

- Field `StartRegistrationOptions.requireResidentKey: boolean` replaced
  with field `authenticatorSelection:
  Optional<AuthenticatorSelectionCriteria>`
  • Loading branch information
emlun committed Oct 5, 2018
2 parents 536bb84 + 01f5295 commit dd85090
Show file tree
Hide file tree
Showing 42 changed files with 397 additions and 630 deletions.
12 changes: 8 additions & 4 deletions NEWS
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
== Version 0.4.0 ==

Breaking changes:

* Field `StartRegistrationOptions.requireResidentKey: boolean` replaced with
field `authenticatorSelection: Optional<AuthenticatorSelectionCriteria>`


== Version 0.3.0 ==

* Major API overhaul; public API changes include but are not limited to:
Expand Down Expand Up @@ -25,10 +33,6 @@
failures
** Class `MetadataResolver` replaced with interface
** Constructor `CollectedClientData(JsonNode)` deleted
** Type of fields `StartAssertionOptions.extensions`,
`StartRegistrationOptions.extensions` and
`PublicKeyCredential.clientExtensionOutputs` narrowed from `JsonNode` to
`ObjectNode`
** Parameters `StartRegistrationOptions.excludeCredentials` and
`StartAssertionOptions.allowCredentials` deleted; they are now discovered
automatically from the `CredentialRepository`. If custom control over
Expand Down
40 changes: 38 additions & 2 deletions README
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
== java-webauthn-server

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

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

See link:webauthn-server-demo[`webauthn-server-demo`] for a complete demo
server, which stores authenticator registrations temporarily in memory.


=== Building

Use the included
https://docs.gradle.org/current/userguide/gradle_wrapper.html[Gradle wrapper] to
build the `.jar` artifact:

```
$ ./gradlew :webauthn-server-core:jar
```

The output is built in the `webauthn-server-core/build/libs/` directory, and the
version is derived from the most recent Git tag. Builds done on a tagged commit
will have a plain `x.y.z` version number, while a build on any other commit will
result in a version number containing the abbreviated commit hash.

Although the `.jar` artifact of this project can be used in JDK version 8 or
later, the project as a whole currently builds only in JDK 8. This is because
most tests are written in Scala, which
https://docs.scala-lang.org/overviews/jdk-compatibility/overview.html#jdk-9\--up-compatibility-notes[currently
only supports JDK 8]. Therefore compiling the tests can currently only be done
in JDK 8, and so `./gradlew build` and similar tasks will fail in JDKs other
than 8.

To run the tests (requires JDK 8):

```
$ ./gradlew check
```

To run the http://pitest.org/[PIT mutation tests] (requires JDK 8):

```
$ ./gradlew pitest
```
36 changes: 22 additions & 14 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ buildscript {
}
dependencies {
configurations.maybeCreate('pitest')
classpath 'com.cinnober.gradle:semver-git:2.3.1'
classpath 'com.cinnober.gradle:semver-git:2.4.0'
classpath 'info.solidsoft.gradle.pitest:gradle-pitest-plugin:1.3.0'
pitest 'org.pitest:pitest-command-line:1.4.2' // Transitive dependency from pitest plugin
}
Expand All @@ -15,8 +15,11 @@ plugins {
id 'net.researchgate.release' version '2.4.0'
}

project.ext.isCiBuild = System.env.CI == 'true'

project.ext.publishEnabled = System.env.CI != 'true' && project.hasProperty('ossrhUsername')
project.ext.publishEnabled = !isCiBuild &&
project.hasProperty('yubicoPublish') && project.yubicoPublish &&
project.hasProperty('ossrhUsername') && project.hasProperty('ossrhPassword')

if (publishEnabled) {
nexusStaging {
Expand All @@ -31,22 +34,13 @@ task wrapper(type: Wrapper) {
}

allprojects {
ext.snapshotSuffix = "<count>.g<sha>-SNAPSHOT"
ext.snapshotSuffix = "<count>.g<sha>-SNAPSHOT<dirty>"
ext.dirtyMarker = "-DIRTY"

apply plugin: 'com.cinnober.gradle.semver-git'
apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'signing'
apply plugin: 'idea'

if (publishEnabled) {
signing {
useGpgCmd()
sign configurations.archives
}
signArchives.dependsOn check
}

group = 'com.yubico'

sourceCompatibility = 1.8
Expand All @@ -67,6 +61,10 @@ allprojects {

test {
failFast = true

testLogging {
showStandardStreams = isCiBuild
}
}
}

Expand Down Expand Up @@ -101,7 +99,17 @@ subprojects {

}

if (publishEnabled) {
if (publishEnabled && project.hasProperty('publishMe') && project.publishMe) {

apply plugin: 'maven'
apply plugin: 'signing'

signing {
useGpgCmd()
sign configurations.archives
}
signArchives.dependsOn check

uploadArchives {
repositories {
mavenDeployer {
Expand Down
2 changes: 2 additions & 0 deletions webauthn-server-attestation/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ description = 'Yubico WebAuthn attestation subsystem'

apply plugin: 'java'

project.ext.publishMe = true

dependencies {

compile(
Expand Down
29 changes: 29 additions & 0 deletions webauthn-server-core/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
= Web Authentication server library

Implementation of a Web Authentication Relying Party (RP).


== Running

An example app is included in the
link:../webauthn-server-demo[`webauthn-server-demo`] directory. See
link:../webauthn-server-demo/README[its README] for instructions on how to run
it.


== Unimplemented features

* https://www.w3.org/TR/webauthn/#ecdaa[ECDAA] attestation type
* Attestation statement formats:
** https://www.w3.org/TR/webauthn/#tpm-attestation[`tpm`]
** https://www.w3.org/TR/webauthn/#android-key-attestation[`android-key`]
** https://www.w3.org/TR/webauthn/#android-safetynet-attestation[`android-safetynet`]
* Extensions:
** https://www.w3.org/TR/webauthn/#sctn-simple-txauth-extension[`txAuthSimple`]
** https://www.w3.org/TR/webauthn/#sctn-generic-txauth-extension[`txAuthGeneric`]
** https://www.w3.org/TR/webauthn/#sctn-authenticator-selection-extension[`authnSel`]
** https://www.w3.org/TR/webauthn/#sctn-supported-extensions-extension[`exts`]
** https://www.w3.org/TR/webauthn/#sctn-uvi-extension[`uvi`]
** https://www.w3.org/TR/webauthn/#sctn-location-extension[`loc`]
** https://www.w3.org/TR/webauthn/#sctn-uvm-extension[`uvm`]
** https://www.w3.org/TR/webauthn/#sctn-authenticator-biometric-criteria-extension[`biometricPerfBounds`]
1 change: 1 addition & 0 deletions webauthn-server-core/README.adoc
33 changes: 0 additions & 33 deletions webauthn-server-core/README.md

This file was deleted.

25 changes: 1 addition & 24 deletions webauthn-server-core/build.gradle
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import java.nio.file.Paths

apply plugin: 'info.solidsoft.pitest'

description = 'WebAuthn core API'

apply plugin: 'scala'

configurations {
scalaRepl { extendsFrom testRuntime }
}
project.ext.publishMe = true

dependencies {

Expand All @@ -31,11 +27,6 @@ dependencies {
'org.scalacheck:scalacheck_2.11:1.13.5',
)

scalaRepl(
'org.scala-lang:scala-compiler:2.11.3',
jar.outputs.files,
)

}


Expand Down Expand Up @@ -68,17 +59,3 @@ pitest {
]
}

def scalaReplDistDir = file(Paths.get(project.distsDir.path, 'scala-repl'))
task scalaReplClasspath(type: Sync) {
from configurations.scalaRepl
destinationDir = file(Paths.get(scalaReplDistDir.path, 'lib'))
}

task makeScalaReplScripts(type: CreateStartScripts) {
inputs.files tasks.scalaReplClasspath.outputs

applicationName = 'scala-repl'
classpath = configurations.scalaRepl
mainClassName = "scala.tools.nsc.MainGenericRunner"
outputDir = file(Paths.get(scalaReplDistDir.path, 'bin'))
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.fasterxml.jackson.core.Base64Variants;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.dataformat.cbor.CBORFactory;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
Expand All @@ -28,6 +29,7 @@ public static ObjectMapper cbor() {
public static ObjectMapper json() {
return new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true)
.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
.setSerializationInclusion(Include.NON_ABSENT)
.setBase64Variant(Base64Variants.MODIFIED_FOR_URL)
.registerModule(new Jdk8Module())
Expand Down Expand Up @@ -84,7 +86,7 @@ public static ByteArray rawEcdaKeyToCose(ByteArray key) {
Map<Long, Object> coseKey = new HashMap<>();

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

public static COSEAlgorithmIdentifier javaAlgorithmNameToCoseAlgorithmIdentifier(String alg) {
switch (alg) {
case "ECDSA":
case "ES256":
return COSEAlgorithmIdentifier.ES256;

case "RS256":
return COSEAlgorithmIdentifier.RS256;
}

throw new IllegalArgumentException("Unknown algorithm: " + alg);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import com.yubico.webauthn.data.AttestationConveyancePreference;
import com.yubico.webauthn.data.AuthenticatorAssertionResponse;
import com.yubico.webauthn.data.AuthenticatorAttestationResponse;
import com.yubico.webauthn.data.AuthenticatorSelectionCriteria;
import com.yubico.webauthn.data.ByteArray;
import com.yubico.webauthn.data.ClientAssertionExtensionOutputs;
import com.yubico.webauthn.data.ClientRegistrationExtensionOutputs;
Expand Down Expand Up @@ -68,11 +67,7 @@ public PublicKeyCredentialCreationOptions startRegistration(StartRegistrationOpt
.excludeCredentials(
Optional.of(credentialRepository.getCredentialIdsForUsername(startRegistrationOptions.getUser().getName()))
)
.authenticatorSelection(Optional.of(
AuthenticatorSelectionCriteria.builder()
.requireResidentKey(startRegistrationOptions.isRequireResidentKey())
.build()
))
.authenticatorSelection(startRegistrationOptions.getAuthenticatorSelection())
.attestation(attestationConveyancePreference.orElse(AttestationConveyancePreference.DEFAULT))
.extensions(startRegistrationOptions.getExtensions())
.build();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.yubico.webauthn;

import com.yubico.webauthn.data.AuthenticatorSelectionCriteria;
import com.yubico.webauthn.data.RegistrationExtensionInputs;
import com.yubico.webauthn.data.UserIdentity;
import java.util.Optional;
import lombok.Builder;
import lombok.NonNull;
import lombok.Value;
Expand All @@ -15,9 +17,10 @@ public class StartRegistrationOptions {

@NonNull
@Builder.Default
private final RegistrationExtensionInputs extensions = RegistrationExtensionInputs.builder().build();
private final Optional<AuthenticatorSelectionCriteria> authenticatorSelection = Optional.empty();

@NonNull
@Builder.Default
private final boolean requireResidentKey = false;
private final RegistrationExtensionInputs extensions = RegistrationExtensionInputs.builder().build();

}

This file was deleted.

Loading

0 comments on commit dd85090

Please sign in to comment.