Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import org.scalatest.tags.Network
import org.scalatest.tags.Slow
import org.scalatestplus.junit.JUnitRunner

import java.util.Collections
import scala.jdk.CollectionConverters.ListHasAsScala

@Slow
Expand Down Expand Up @@ -52,14 +51,12 @@ class FidoMetadataDownloaderIntegrationTest
.cacheSynchronized(
downloader
.fetchHeaderCertChain(
Collections.singleton(
FidoMetadataDownloader.importTrustAnchor(trustRootCert)
),
downloader
.parseBlob(TestCaches.blobCache.get.getBytes)
.getBlob
.getHeader,
.getHeader
)
.get
)
.asScala :+ trustRootCert
for { cert <- certChain } {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1351,7 +1351,42 @@
InvalidAlgorithmParameterException,
FidoMetadataDownloaderException {
final MetadataBLOBHeader header = parseResult.blob.getHeader();
final List<X509Certificate> certChain = fetchHeaderCertChain(trustAnchors, header);
final Optional<List<X509Certificate>> certChain = fetchHeaderCertChain(header);
if (certChain.isPresent()) {
return tryVerifyBlob(parseResult, trustAnchors, certChain.get());
} else {
log.debug(
"x5u and x5c both missing from BLOB header. Falling back to using trust anchors as BLOB signer.");
for (TrustAnchor ta : trustAnchors) {
final X509Certificate cert = ta.getTrustedCert();
if (cert != null) {
try {
return tryVerifyBlob(parseResult, trustAnchors, Collections.singletonList(cert));
} catch (FidoMetadataDownloaderException e) {
if (e.getReason() == Reason.BAD_SIGNATURE) {
log.debug("Failed to verify BLOB with trust anchor: {}", ta);
} else {
throw e;
}
} catch (SignatureException | CertPathValidatorException e) {
log.debug("Failed to verify BLOB with trust anchor: {}", ta);
}
}
}
throw new IllegalArgumentException("Failed to verify BLOB with any trust anchor.");
}
}

private MetadataBLOB tryVerifyBlob(
ParseResult parseResult, Set<TrustAnchor> trustAnchors, List<X509Certificate> certChain)
throws CertificateException,
NoSuchAlgorithmException,
InvalidKeyException,
SignatureException,
CertPathValidatorException,
InvalidAlgorithmParameterException,
FidoMetadataDownloaderException {
final MetadataBLOBHeader header = parseResult.blob.getHeader();
final X509Certificate leafCert = certChain.get(0);

final Signature signature;
Expand Down Expand Up @@ -1470,8 +1505,7 @@
}

/** Parse the header cert chain and download any certificates as necessary. */
List<X509Certificate> fetchHeaderCertChain(
Set<TrustAnchor> trustAnchors, MetadataBLOBHeader header)
Optional<List<X509Certificate>> fetchHeaderCertChain(MetadataBLOBHeader header)
throws IOException, CertificateException {
if (header.getX5u().isPresent()) {
final URL x5u = header.getX5u().get();
Expand All @@ -1492,18 +1526,11 @@
X509Certificate x509Certificate = CertificateParser.parsePem(pem);
certs.add(x509Certificate);
}
return certs;
return Optional.of(certs);
} else if (header.getX5c().isPresent()) {
return header.getX5c().get();
return Optional.of(header.getX5c().get());
} else {
return trustAnchors.stream()
.map(TrustAnchor::getTrustedCert)
.findFirst()
.map(Collections::singletonList)
.orElseThrow(
() ->
new IllegalArgumentException(
"x5u and x5c both missing from BLOB header, and no given trust anchor could be interpreted as an X509Certificate."));
return Optional.empty();
}
}

Expand Down Expand Up @@ -1608,7 +1635,7 @@

@Value
@Builder
@Jacksonized

Check warning on line 1638 in webauthn-server-attestation/src/main/java/com/yubico/fido/metadata/FidoMetadataDownloader.java

View workflow job for this annotation

GitHub Actions / JDK 21 temurin

Ambiguous: Jackson2 and Jackson3 exist; define which variant(s) you want in 'lombok.config'. See https://projectlombok.org/features/experimental/Jacksonized

Check warning on line 1638 in webauthn-server-attestation/src/main/java/com/yubico/fido/metadata/FidoMetadataDownloader.java

View workflow job for this annotation

GitHub Actions / JDK 25 zulu

Ambiguous: Jackson2 and Jackson3 exist; define which variant(s) you want in 'lombok.config'. See https://projectlombok.org/features/experimental/Jacksonized

Check warning on line 1638 in webauthn-server-attestation/src/main/java/com/yubico/fido/metadata/FidoMetadataDownloader.java

View workflow job for this annotation

GitHub Actions / JDK 25 microsoft

Ambiguous: Jackson2 and Jackson3 exist; define which variant(s) you want in 'lombok.config'. See https://projectlombok.org/features/experimental/Jacksonized

Check warning on line 1638 in webauthn-server-attestation/src/main/java/com/yubico/fido/metadata/FidoMetadataDownloader.java

View workflow job for this annotation

GitHub Actions / JDK 25 temurin

Ambiguous: Jackson2 and Jackson3 exist; define which variant(s) you want in 'lombok.config'. See https://projectlombok.org/features/experimental/Jacksonized

Check warning on line 1638 in webauthn-server-attestation/src/main/java/com/yubico/fido/metadata/FidoMetadataDownloader.java

View workflow job for this annotation

GitHub Actions / JDK 17 temurin

Ambiguous: Jackson2 and Jackson3 exist; define which variant(s) you want in 'lombok.config'. See https://projectlombok.org/features/experimental/Jacksonized

Check warning on line 1638 in webauthn-server-attestation/src/main/java/com/yubico/fido/metadata/FidoMetadataDownloader.java

View workflow job for this annotation

GitHub Actions / JDK 25 microsoft

Ambiguous: Jackson2 and Jackson3 exist; define which variant(s) you want in 'lombok.config'. See https://projectlombok.org/features/experimental/Jacksonized

Check warning on line 1638 in webauthn-server-attestation/src/main/java/com/yubico/fido/metadata/FidoMetadataDownloader.java

View workflow job for this annotation

GitHub Actions / JDK 25 temurin

Ambiguous: Jackson2 and Jackson3 exist; define which variant(s) you want in 'lombok.config'. See https://projectlombok.org/features/experimental/Jacksonized

Check warning on line 1638 in webauthn-server-attestation/src/main/java/com/yubico/fido/metadata/FidoMetadataDownloader.java

View workflow job for this annotation

GitHub Actions / JDK 25 zulu

Ambiguous: Jackson2 and Jackson3 exist; define which variant(s) you want in 'lombok.config'. See https://projectlombok.org/features/experimental/Jacksonized

Check warning on line 1638 in webauthn-server-attestation/src/main/java/com/yubico/fido/metadata/FidoMetadataDownloader.java

View workflow job for this annotation

GitHub Actions / JDK 21 temurin

Ambiguous: Jackson2 and Jackson3 exist; define which variant(s) you want in 'lombok.config'. See https://projectlombok.org/features/experimental/Jacksonized

Check warning on line 1638 in webauthn-server-attestation/src/main/java/com/yubico/fido/metadata/FidoMetadataDownloader.java

View workflow job for this annotation

GitHub Actions / JDK 17 temurin

Ambiguous: Jackson2 and Jackson3 exist; define which variant(s) you want in 'lombok.config'. See https://projectlombok.org/features/experimental/Jacksonized
static class TrustRootsCacheValue {
List<String> urls;
List<byte[]> certsDer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode
import com.yubico.fido.metadata.FidoMetadataDownloader.CachePolicyDecision
import com.yubico.fido.metadata.FidoMetadataDownloader.FidoMetadataDownloaderBuilder
import com.yubico.fido.metadata.FidoMetadataDownloader.TrustRootsCacheValue
import com.yubico.fido.metadata.FidoMetadataDownloader.importTrustAnchor
import com.yubico.fido.metadata.FidoMetadataDownloaderException.Reason
import com.yubico.internal.util.BinaryUtil
import com.yubico.internal.util.JacksonCodecs
Expand Down Expand Up @@ -1958,7 +1959,13 @@ class FidoMetadataDownloaderSpec
}

it("Missing x5c means the trust root cert is used as the signer.") {
val (trustRootCert, caKeypair, caName) = makeTrustRootCert()
val (trustRootCert, caKeypair, caName) =
makeTrustRootCert(distinguishedName =
"CN=Yubico java-webauthn-server unit tests CA 1, O=Yubico"
)
val (trustRootCert0, _, _) = makeTrustRootCert(distinguishedName =
"CN=Yubico java-webauthn-server unit tests CA 0, O=Yubico"
)
val blobJwt =
makeBlob(
caKeypair,
Expand Down Expand Up @@ -1987,7 +1994,9 @@ class FidoMetadataDownloaderSpec
.expectLegalHeader(
"Kom ihåg att du aldrig får snyta dig i mattan!"
)
.useTrustRoot(trustRootCert)
.useTrustRoots(
Set(trustRootCert0, trustRootCert).map(importTrustAnchor).asJava
)
.useBlob(blobJwt)
.useCrls(crls.asJava)
.clock(Clock.fixed(CertValidFrom, ZoneOffset.UTC))
Expand Down
Loading