Skip to content

Commit

Permalink
Release 1.3.0
Browse files Browse the repository at this point in the history
Security fixes:

- Bumped Jackson dependency to version 2.9.9 which has patched
  CVE-2019-12086

New features:

- New optional parameter `timeout` added to `StartRegistrationOptions`
  and `StartAssertionOptions`

Bug fixes:

- Fixed polarity error in javadoc for
  `RelyingParty.allowUntrustedAttestation`
  • Loading branch information
emlun committed Jun 4, 2019
2 parents 050de23 + a003f64 commit 6ade42d
Show file tree
Hide file tree
Showing 19 changed files with 272 additions and 82 deletions.
23 changes: 5 additions & 18 deletions .travis.yml
Expand Up @@ -2,37 +2,24 @@ language: java

branches:
except:
- tmp

env:
global:
secure: sX5sJd2EUgzIT7uQN0YxA3faVHymBG/QPZ/St5IPqoQIXjZAMYBM0D1MrVOYaSOhgVKOJt+5vwCYU7MlY9Ha0rUPJgUPT+6CkVgUVCsQ1e8srAzaYp4ceIYaW2XpUIwhKHPBezulV3nLANRs0FibEN+eqTgL5A/qKtsU49BtQ1iUAVFFOzGcR48avo1UYxS0FLw+7MRLgH5NA6KJVHiGChx9P3oLYAhPylgDzRv6iFf5H5v9azQI4eLo6bSQwm++j0UpH4t8m+at7eGuzNsadYY0M9SoUwuJxQZiwtImYJJtGJD92QtV9m+yny4+RocXchgZDj3e9vx06ZqXaeF3U3o49YUX5ACerVV12yOxGZsuuxfevaQa9Mk4xEOwGkhva5I+8vfo8MRxm7ymelExn25zpsMlmj6GjBio3z1q/FGYdyXrcGoVNrvAgozs+0yW2jYtDVo7DNu8J2mur/C/gmi+xA6rkuEJQIQ3hWuWYVe7DUzdii5MG9/9AdwI14b3uyezh1EJ8tza5MScDQijTvD9sGxarruKS59VuJapqrJSU5E87CnlU6gQx7qXJVGvpTXZOw7ZzsdszSDQ3Jc9uNBSdtBQ2i7egEyTE+RQWsdtje/H0s3ZYyIw8qrQ1kIUDQKk7jl8Uvwf+zn/36JBgZMVIIO0hmDFnyB9wBGd7lk=
- /^tmp-?.*/

jdk:
- openjdk8
- oraclejdk8
- oraclejdk11
- openjdk8
- openjdk10
- openjdk11

script:
- ./gradlew check assembleJavadoc

stages:
- test
- mutation-test
- deploy

jobs:
include:
- stage: mutation-test
jdk: oraclejdk8
script: ./gradlew pitest coveralls

- stage: deploy
jdk: oraclejdk8
script: ./gradlew assembleJavadoc
deploy:
provider: pages
skip-cleanup: true
github-token: $PAGES_DEPLOY_KEY
on:
branch: master
local-dir: 'build/javadoc'
16 changes: 16 additions & 0 deletions NEWS
@@ -1,3 +1,19 @@
== Version 1.3.0 ==

Security fixes:

* Bumped Jackson dependency to version 2.9.9 which has patched CVE-2019-12086

New features:

* New optional parameter `timeout` added to `StartRegistrationOptions` and
`StartAssertionOptions`

Bug fixes:

* Fixed polarity error in javadoc for `RelyingParty.allowUntrustedAttestation`


== Version 1.2.0 ==

New features:
Expand Down
29 changes: 10 additions & 19 deletions README
Expand Up @@ -14,8 +14,6 @@ for a server to support Web Authentication. This includes registering
authenticators and authenticating registered authenticators.


== Table of contents

toc::[]


Expand All @@ -27,15 +25,15 @@ Maven:
<dependency>
<groupId>com.yubico</groupId>
<artifactId>webauthn-server-core</artifactId>
<version>1.2.0</version>
<version>1.3.0</version>
<scope>compile</scope>
</dependency>
----------

Gradle:

----------
compile 'com.yubico:webauthn-server-core:1.2.0'
compile 'com.yubico:webauthn-server-core:1.3.0'
----------


Expand All @@ -46,6 +44,7 @@ compile 'com.yubico:webauthn-server-core:1.2.0'
- Performs all necessary
https://www.w3.org/TR/webauthn/#rp-operations[validation logic] on the
response from the client
- No mutable state or side effects - everything (except builders) is thread safe
- Optionally integrates with a "metadata service" to verify
https://www.w3.org/TR/webauthn/#sctn-attestation[authenticator attestations]
and annotate responses with additional authenticator metadata
Expand All @@ -67,30 +66,30 @@ but the authentication mechanism alone does not make a security system.
link:https://bugs.chromium.org/p/chromium/issues/detail?id=847878[bug in
Chrome] which will not be worked around here. To work around this in
application code, you can omit the
link:https://yubico.github.io/java-webauthn-server/webauthn-server-core/com/yubico/webauthn/data/AuthenticatorAssertionResponse.AuthenticatorAssertionResponseBuilder.html#userHandle-java.util.Optional[`userHandle`]
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`]
when constructing an
link:https://yubico.github.io/java-webauthn-server/webauthn-server-core/com/yubico/webauthn/data/AuthenticatorAssertionResponse.html[`AuthenticatorAssertionResponse`]
link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/latest/com/yubico/webauthn/data/AuthenticatorAssertionResponse.html[`AuthenticatorAssertionResponse`]
value if the `userHandle` is empty. See
https://github.com/Yubico/java-webauthn-server/issues/12 .


== Documentation

See the
link:https://yubico.github.io/java-webauthn-server/webauthn-server-core/com/yubico/webauthn/package-summary.html[Javadoc]
link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/latest/com/yubico/webauthn/package-summary.html[Javadoc]
for in-depth API documentation.


== Quick start

Implement the
link:https://yubico.github.io/java-webauthn-server/webauthn-server-core/com/yubico/webauthn/CredentialRepository.html[`CredentialRepository`]
link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/latest/com/yubico/webauthn/CredentialRepository.html[`CredentialRepository`]
interface with your database access logic. See
link:https://github.com/Yubico/java-webauthn-server/blob/master/webauthn-server-demo/src/main/java/demo/webauthn/InMemoryRegistrationStorage.java[`InMemoryRegistrationStorage`]
for an example.

Instantiate the
link:https://yubico.github.io/java-webauthn-server/webauthn-server-core/com/yubico/webauthn/RelyingParty.html[`RelyingParty`]
link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-core/latest/com/yubico/webauthn/RelyingParty.html[`RelyingParty`]
class:

[source,java]
Expand Down Expand Up @@ -328,21 +327,13 @@ 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):
To run the tests:

----------
$ ./gradlew check
----------

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

----------
$ ./gradlew pitest
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Expand Up @@ -139,7 +139,7 @@ subprojects { project ->

testCompile(
'junit:junit:4.12',
'org.mockito:mockito-core:2.8.47',
'org.mockito:mockito-core:2.27.0',
)

}
Expand Down
8 changes: 4 additions & 4 deletions webauthn-server-attestation/build.gradle
Expand Up @@ -16,10 +16,10 @@ dependencies {
project(':webauthn-server-core').sourceSets.test.output,
project(':yubico-util-scala'),
'commons-io:commons-io:2.5',
'org.mockito:mockito-core:2.10.0',
'org.scala-lang:scala-library:2.11.3',
'org.scalacheck:scalacheck_2.11:1.13.5',
'org.scalatest:scalatest_2.11:3.0.4',
'org.mockito:mockito-core:2.27.0',
'org.scala-lang:scala-library:2.12.8',
'org.scalacheck:scalacheck_2.12:1.14.0',
'org.scalatest:scalatest_2.12:3.0.4',
)
}

Expand Down
Expand Up @@ -101,7 +101,7 @@ class StandardMetadataServiceSpec extends FunSpec with Matchers {
s"""{
"identifier": "44c87ead-4455-423e-88eb-9248e0ebe847",
"version": 1,
"trustedCertificates": ["${TestAuthenticator.toPem(caCert).lines.mkString(raw"\n")}"],
"trustedCertificates": ["${TestAuthenticator.toPem(caCert).linesIterator.mkString(raw"\n")}"],
"vendorInfo": {},
"devices": [
{
Expand Down Expand Up @@ -159,7 +159,7 @@ class StandardMetadataServiceSpec extends FunSpec with Matchers {
s"""{
"identifier": "44c87ead-4455-423e-88eb-9248e0ebe847",
"version": 1,
"trustedCertificates": ["${TestAuthenticator.toPem(caCert).lines.mkString(raw"\n")}"],
"trustedCertificates": ["${TestAuthenticator.toPem(caCert).linesIterator.mkString(raw"\n")}"],
"vendorInfo": {},
"devices": []
}"""
Expand Down Expand Up @@ -197,7 +197,7 @@ class StandardMetadataServiceSpec extends FunSpec with Matchers {
s"""{
"identifier": "44c87ead-4455-423e-88eb-9248e0ebe847",
"version": 1,
"trustedCertificates": ["${TestAuthenticator.toPem(cacaca._1).lines.mkString(raw"\n")}"],
"trustedCertificates": ["${TestAuthenticator.toPem(cacaca._1).linesIterator.mkString(raw"\n")}"],
"vendorInfo": {},
"devices": [
{
Expand Down Expand Up @@ -227,7 +227,7 @@ class StandardMetadataServiceSpec extends FunSpec with Matchers {
s"""{
"identifier": "44c87ead-4455-423e-88eb-9248e0ebe847",
"version": 1,
"trustedCertificates": ["${TestAuthenticator.toPem(caCert).lines.mkString(raw"\n")}"],
"trustedCertificates": ["${TestAuthenticator.toPem(caCert).linesIterator.mkString(raw"\n")}"],
"vendorInfo": {},
"devices": [
{
Expand Down
14 changes: 7 additions & 7 deletions webauthn-server-core/build.gradle
Expand Up @@ -11,9 +11,9 @@ dependencies {
compile(
project(':yubico-util'),
'com.augustcellars.cose:cose-java:0.9.4',
'com.fasterxml.jackson.core:jackson-databind:2.9.6',
'com.fasterxml.jackson.dataformat:jackson-dataformat-cbor:2.9.6',
'com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.9.6',
'com.fasterxml.jackson.core:jackson-databind:2.9.9',
'com.fasterxml.jackson.dataformat:jackson-dataformat-cbor:2.9.9',
'com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.9.9',
'com.google.guava:guava:19.0',
'org.apache.httpcomponents:httpclient:4.5.2',
'org.bouncycastle:bcpkix-jdk15on:1.54',
Expand All @@ -22,10 +22,10 @@ dependencies {
testCompile(
project(':yubico-util-scala'),
'commons-io:commons-io:2.5',
'org.mockito:mockito-core:2.10.0',
'org.scala-lang:scala-library:2.11.3',
'org.scalacheck:scalacheck_2.11:1.13.5',
'org.scalatest:scalatest_2.11:3.0.4',
'org.mockito:mockito-core:2.27.0',
'org.scala-lang:scala-library:2.12.8',
'org.scalacheck:scalacheck_2.12:1.14.0',
'org.scalatest:scalatest_2.12:3.0.4',
)

}
Expand Down
Expand Up @@ -223,7 +223,7 @@ public class RelyingParty {
private final boolean allowUnrequestedExtensions = false;

/**
* If <code>true</code>, {@link #finishRegistration(FinishRegistrationOptions) finishRegistration} will only allow
* If <code>false</code>, {@link #finishRegistration(FinishRegistrationOptions) finishRegistration} will only allow
* registrations where the attestation signature can be linked to a trusted attestation root. This excludes self
* attestation and none attestation.
*
Expand Down Expand Up @@ -292,6 +292,7 @@ public PublicKeyCredentialCreationOptions startRegistration(StartRegistrationOpt
)
.authenticatorSelection(startRegistrationOptions.getAuthenticatorSelection())
.extensions(startRegistrationOptions.getExtensions())
.timeout(startRegistrationOptions.getTimeout())
;
attestationConveyancePreference.ifPresent(builder::attestation);
return builder.build();
Expand Down Expand Up @@ -344,6 +345,7 @@ public AssertionRequest startAssertion(StartAssertionOptions startAssertionOptio
.appid(appId)
.build()
)
.timeout(startAssertionOptions.getTimeout())
;

startAssertionOptions.getUserVerification().ifPresent(pkcro::userVerification);
Expand Down
Expand Up @@ -80,9 +80,24 @@ public class StartAssertionOptions {
@NonNull
private final Optional<UserVerificationRequirement> userVerification;

/**
* The value for {@link PublicKeyCredentialRequestOptions#getTimeout()} for this authentication operation.
* <p>
* This library does not take the timeout into account in any way, other than passing it through to the {@link
* PublicKeyCredentialRequestOptions} so it can be used as an argument to
* <code>navigator.credentials.get()</code> on the client side.
* </p>
* <p>
* The default is empty.
* </p>
*/
@NonNull
private final Optional<Long> timeout;

public static class StartAssertionOptionsBuilder {
private @NonNull Optional<String> username = Optional.empty();
private @NonNull Optional<UserVerificationRequirement> userVerification = Optional.empty();
private @NonNull Optional<Long> timeout = Optional.empty();

/**
* The username of the user to authenticate, if the user has already been identified.
Expand Down Expand Up @@ -141,5 +156,39 @@ public StartAssertionOptionsBuilder userVerification(@NonNull Optional<UserVerif
public StartAssertionOptionsBuilder userVerification(@NonNull UserVerificationRequirement userVerification) {
return this.userVerification(Optional.of(userVerification));
}

/**
* The value for {@link PublicKeyCredentialRequestOptions#getTimeout()} for this authentication operation.
* <p>
* This library does not take the timeout into account in any way, other than passing it through to the {@link
* PublicKeyCredentialRequestOptions} so it can be used as an argument to
* <code>navigator.credentials.get()</code> on the client side.
* </p>
* <p>
* The default is empty.
* </p>
*/
public StartAssertionOptionsBuilder timeout(@NonNull Optional<Long> timeout) {
if (timeout.isPresent() && timeout.get() <= 0) {
throw new IllegalArgumentException("timeout must be positive, was: " + timeout.get());
}
this.timeout = timeout;
return this;
}

/**
* The value for {@link PublicKeyCredentialRequestOptions#getTimeout()} for this authentication operation.
* <p>
* This library does not take the timeout into account in any way, other than passing it through to the {@link
* PublicKeyCredentialRequestOptions} so it can be used as an argument to
* <code>navigator.credentials.get()</code> on the client side.
* </p>
* <p>
* The default is empty.
* </p>
*/
public StartAssertionOptionsBuilder timeout(long timeout) {
return this.timeout(Optional.of(timeout));
}
}
}

0 comments on commit 6ade42d

Please sign in to comment.