Skip to content

Commit d26964c

Browse files
authored
Merge pull request #392 from Yubico/parse-crldp-extension
Fetch CRLDistributionPoints in FidoMetadataDownloader
2 parents 45a4ca6 + b28e10e commit d26964c

File tree

17 files changed

+849
-223
lines changed

17 files changed

+849
-223
lines changed

NEWS

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
== Version 2.6.0 (unreleased) ==
22

3+
`webauthn-server-core`:
4+
35
New features:
46

57
* Added method `getParsedPublicKey(): java.security.PublicKey` to
@@ -61,6 +63,14 @@ New features:
6163
version increase.
6264
* (Experimental) Added `credProps` extension to assertion extension outputs.
6365

66+
`webauthn-server-attestation`:
67+
68+
New features:
69+
70+
* `FidoMetadataDownloader` now parses the CRLDistributionPoints extension on the
71+
application level, so the `com.sun.security.enableCRLDP=true` system property
72+
setting is no longer necessary.
73+
6474

6575
== Version 2.5.4 ==
6676

webauthn-server-attestation/README.adoc

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -222,17 +222,6 @@ RegistrationResult result = rp.finishRegistration(/* ... */);
222222
Set<MetadataBLOBPayloadEntry> metadata = mds.findEntries(result);
223223
----------
224224

225-
5. If you use the SUN provider for the `PKIX` certificate path validation algorithm, which many deployments do by default:
226-
set the `com.sun.security.enableCRLDP` system property to `true`.
227-
This is required for the SUN `PKIX` provider to support the CRL Distribution Points extension,
228-
which is needed in order to verify the BLOB signature.
229-
+
230-
For example, this can be done on the JVM command line using a `-Dcom.sun.security.enableCRLDP=true` option.
231-
See the https://docs.oracle.com/javase/9/security/java-pki-programmers-guide.htm#GUID-EB250086-0AC1-4D60-AE2A-FC7461374746__SECTION-139-623E860E[Java PKI Programmers Guide]
232-
for details.
233-
+
234-
This step may not be necessary if you use a different provider for the `PKIX` certificate path validation algorithm.
235-
236225

237226
== Selecting trusted authenticators
238227

webauthn-server-attestation/build.gradle.kts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,12 @@ dependencies {
4848
testImplementation("org.scalatestplus:junit-4-13_2.13")
4949
testImplementation("org.scalatestplus:scalacheck-1-16_2.13")
5050

51-
testImplementation("org.slf4j:slf4j-api")
51+
testImplementation("org.slf4j:slf4j-api") {
52+
version {
53+
strictly("[1.7.25,1.8-a)") // Pre-1.8 version required by slf4j-test
54+
}
55+
}
56+
testRuntimeOnly("uk.org.lidalia:slf4j-test")
5257
}
5358

5459
val integrationTest = task<Test>("integrationTest") {
@@ -58,9 +63,6 @@ val integrationTest = task<Test>("integrationTest") {
5863
testClassesDirs = sourceSets["integrationTest"].output.classesDirs
5964
classpath = sourceSets["integrationTest"].runtimeClasspath
6065
shouldRunAfter(tasks.test)
61-
62-
// Required for processing CRL distribution points extension
63-
systemProperty("com.sun.security.enableCRLDP", "true")
6466
}
6567
tasks["check"].dependsOn(integrationTest)
6668

webauthn-server-attestation/src/integrationTest/scala/com/yubico/fido/metadata/FidoMetadataDownloaderIntegrationTest.scala

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.yubico.fido.metadata
22

3+
import com.yubico.internal.util.CertificateParser
4+
import com.yubico.webauthn.data.ByteArray
35
import org.junit.runner.RunWith
46
import org.scalatest.BeforeAndAfter
57
import org.scalatest.funspec.AnyFunSpec
@@ -8,7 +10,8 @@ import org.scalatest.tags.Network
810
import org.scalatest.tags.Slow
911
import org.scalatestplus.junit.JUnitRunner
1012

11-
import java.util.Optional
13+
import scala.jdk.CollectionConverters.ListHasAsScala
14+
import scala.jdk.OptionConverters.RichOption
1215
import scala.util.Success
1316
import scala.util.Try
1417

@@ -21,24 +24,56 @@ class FidoMetadataDownloaderIntegrationTest
2124
with BeforeAndAfter {
2225

2326
describe("FidoMetadataDownloader with default settings") {
27+
// Cache downloaded items to avoid cause unnecessary load on remote servers
28+
var trustRootCache: Option[ByteArray] = None
29+
var blobCache: Option[ByteArray] = None
2430
val downloader =
2531
FidoMetadataDownloader
2632
.builder()
2733
.expectLegalHeader(
2834
"Retrieval and use of this BLOB indicates acceptance of the appropriate agreement located at https://fidoalliance.org/metadata/metadata-legal-terms/"
2935
)
3036
.useDefaultTrustRoot()
31-
.useTrustRootCache(() => Optional.empty(), _ => {})
37+
.useTrustRootCache(
38+
() => trustRootCache.toJava,
39+
trustRoot => { trustRootCache = Some(trustRoot) },
40+
)
3241
.useDefaultBlob()
33-
.useBlobCache(() => Optional.empty(), _ => {})
42+
.useBlobCache(
43+
() => blobCache.toJava,
44+
blob => { blobCache = Some(blob) },
45+
)
3446
.build()
3547

3648
it("downloads and verifies the root cert and BLOB successfully.") {
37-
// This test requires the system property com.sun.security.enableCRLDP=true
3849
val blob = Try(downloader.loadCachedBlob)
3950
blob shouldBe a[Success[_]]
4051
blob.get should not be null
4152
}
53+
54+
it(
55+
"does not encounter any CRLDistributionPoints entries in unknown format."
56+
) {
57+
val blob = Try(downloader.loadCachedBlob)
58+
blob shouldBe a[Success[_]]
59+
val trustRootCert =
60+
CertificateParser.parseDer(trustRootCache.get.getBytes)
61+
val certChain = downloader
62+
.fetchHeaderCertChain(
63+
trustRootCert,
64+
FidoMetadataDownloader.parseBlob(blobCache.get).getBlob.getHeader,
65+
)
66+
.asScala :+ trustRootCert
67+
for { cert <- certChain } {
68+
withClue(
69+
s"Unknown CRLDistributionPoints structure in cert [${cert.getSubjectX500Principal}] : ${new ByteArray(cert.getEncoded)}"
70+
) {
71+
CertificateParser
72+
.parseCrlDistributionPointsExtension(cert)
73+
.isAnyDistributionPointUnsupported should be(false)
74+
}
75+
}
76+
}
4277
}
4378

4479
}

webauthn-server-attestation/src/main/java/com/yubico/fido/metadata/AAGUID.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
import com.fasterxml.jackson.annotation.JsonCreator;
44
import com.fasterxml.jackson.annotation.JsonValue;
5+
import com.yubico.internal.util.BinaryUtil;
56
import com.yubico.internal.util.ExceptionUtil;
67
import com.yubico.webauthn.data.ByteArray;
7-
import com.yubico.webauthn.data.exception.HexException;
88
import java.util.regex.Matcher;
99
import java.util.regex.Pattern;
1010
import lombok.AccessLevel;
@@ -105,12 +105,14 @@ private static ByteArray parse(String value) {
105105
Matcher matcher = AAGUID_PATTERN.matcher(value);
106106
if (matcher.find()) {
107107
try {
108-
return ByteArray.fromHex(matcher.group(1))
109-
.concat(ByteArray.fromHex(matcher.group(2)))
110-
.concat(ByteArray.fromHex(matcher.group(3)))
111-
.concat(ByteArray.fromHex(matcher.group(4)))
112-
.concat(ByteArray.fromHex(matcher.group(5)));
113-
} catch (HexException e) {
108+
return new ByteArray(
109+
BinaryUtil.concat(
110+
BinaryUtil.fromHex(matcher.group(1)),
111+
BinaryUtil.fromHex(matcher.group(2)),
112+
BinaryUtil.fromHex(matcher.group(3)),
113+
BinaryUtil.fromHex(matcher.group(4)),
114+
BinaryUtil.fromHex(matcher.group(5))));
115+
} catch (Exception e) {
114116
throw new RuntimeException(
115117
"This exception should be impossible, please file a bug report.", e);
116118
}

0 commit comments

Comments
 (0)