Skip to content

Commit 6d3b5b3

Browse files
committed
Fall back to cached BLOB if MDS BLOB download fails
1 parent 8cf2b92 commit 6d3b5b3

File tree

3 files changed

+29
-10
lines changed

3 files changed

+29
-10
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ Fixes:
5555
`useTrustRootCache`.
5656
* BouncyCastle dependency dropped.
5757
* Guava dependency dropped (but still remains in core module).
58+
* If BLOB download fails, `FidoMetadataDownloader` now correctly falls back to
59+
cache if available.
5860

5961

6062
== Version 2.0.0 ==

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,13 @@ private Optional<MetadataBLOB> refreshBlobInternal(
839839
} else {
840840
throw e;
841841
}
842+
} catch (Exception e) {
843+
if (cached.isPresent()) {
844+
log.warn("Failed to download new BLOB - falling back to cached BLOB.", e);
845+
return cached;
846+
} else {
847+
throw e;
848+
}
842849
}
843850
}
844851

webauthn-server-attestation/src/test/scala/com/yubico/fido/metadata/FidoMetadataDownloaderSpec.scala

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import com.yubico.webauthn.TestAuthenticator
99
import com.yubico.webauthn.data.ByteArray
1010
import com.yubico.webauthn.data.COSEAlgorithmIdentifier
1111
import org.bouncycastle.asn1.x500.X500Name
12+
import org.eclipse.jetty.http.HttpStatus
1213
import org.eclipse.jetty.server.HttpConfiguration
1314
import org.eclipse.jetty.server.HttpConnectionFactory
1415
import org.eclipse.jetty.server.Request
@@ -198,14 +199,16 @@ class FidoMetadataDownloaderSpec
198199
path: String,
199200
response: String,
200201
): (Server, String, X509Certificate) =
201-
makeHttpServer(Map(path -> response.getBytes(StandardCharsets.UTF_8)))
202+
makeHttpServer(
203+
Map(path -> (200, response.getBytes(StandardCharsets.UTF_8)))
204+
)
202205
private def makeHttpServer(
203206
path: String,
204207
response: Array[Byte],
205208
): (Server, String, X509Certificate) =
206-
makeHttpServer(Map(path -> response))
209+
makeHttpServer(Map(path -> (200, response)))
207210
private def makeHttpServer(
208-
responses: Map[String, Array[Byte]]
211+
responses: Map[String, (Int, Array[Byte])]
209212
): (Server, String, X509Certificate) = {
210213
val tlsKey = TestAuthenticator.generateEcKeypair()
211214
val tlsCert = TestAuthenticator.buildCertificate(
@@ -248,9 +251,9 @@ class FidoMetadataDownloaderSpec
248251
response: HttpServletResponse,
249252
): Unit = {
250253
responses.get(target) match {
251-
case Some(responseBody) => {
254+
case Some((status, responseBody)) => {
252255
response.getOutputStream.write(responseBody)
253-
response.setStatus(200)
256+
response.setStatus(status)
254257
}
255258
case None => response.setStatus(404)
256259
}
@@ -1062,7 +1065,7 @@ class FidoMetadataDownloaderSpec
10621065
blob.getNo should equal(blobNo)
10631066
}
10641067

1065-
it("The BLOB is downloaded if the cached one is out of date.") {
1068+
it("The cache is used if the BLOB download fails.") {
10661069
val oldBlobNo = 1
10671070
val newBlobNo = 2
10681071

@@ -1093,7 +1096,12 @@ class FidoMetadataDownloaderSpec
10931096
)
10941097

10951098
val (server, serverUrl, httpsCert) =
1096-
makeHttpServer("/blob.jwt", newBlobJwt)
1099+
makeHttpServer(
1100+
Map(
1101+
"/blob.jwt" -> (HttpStatus.TOO_MANY_REQUESTS_429, newBlobJwt
1102+
.getBytes(StandardCharsets.UTF_8))
1103+
)
1104+
)
10971105
startServer(server)
10981106

10991107
val blob = load(
@@ -1117,7 +1125,7 @@ class FidoMetadataDownloaderSpec
11171125
.build()
11181126
).getPayload
11191127
blob should not be null
1120-
blob.getNo should equal(newBlobNo)
1128+
blob.getNo should equal(oldBlobNo)
11211129
}
11221130
}
11231131

@@ -1152,8 +1160,10 @@ class FidoMetadataDownloaderSpec
11521160
val (server, _, httpsCert) =
11531161
makeHttpServer(
11541162
Map(
1155-
"/chain.pem" -> certChainPem.getBytes(StandardCharsets.UTF_8),
1156-
"/blob.jwt" -> blobJwt.getBytes(StandardCharsets.UTF_8),
1163+
"/chain.pem" -> (200, certChainPem.getBytes(
1164+
StandardCharsets.UTF_8
1165+
)),
1166+
"/blob.jwt" -> (200, blobJwt.getBytes(StandardCharsets.UTF_8)),
11571167
)
11581168
)
11591169
startServer(server)

0 commit comments

Comments
 (0)