@@ -449,7 +449,14 @@ class FidoMetadataDownloaderSpec
449
449
.expectLegalHeader(
450
450
" Kom ihåg att du aldrig får snyta dig i mattan!"
451
451
)
452
- .useDefaultTrustRoot()
452
+ .downloadTrustRoot(
453
+ new URL (" https://localhost:12345/nonexistent.dev.null" ),
454
+ Set (
455
+ TestAuthenticator .sha256(
456
+ new ByteArray (trustRootCert.getEncoded)
457
+ )
458
+ ).asJava,
459
+ )
453
460
.useTrustRootCacheFile(cacheFile)
454
461
.useBlob(blobJwt)
455
462
.clock(Clock .fixed(CertValidFrom , ZoneOffset .UTC ))
@@ -626,7 +633,14 @@ class FidoMetadataDownloaderSpec
626
633
.expectLegalHeader(
627
634
" Kom ihåg att du aldrig får snyta dig i mattan!"
628
635
)
629
- .useDefaultTrustRoot()
636
+ .downloadTrustRoot(
637
+ new URL (" https://localhost:12345/nonexistent.dev.null" ),
638
+ Set (
639
+ TestAuthenticator .sha256(
640
+ new ByteArray (trustRootCert.getEncoded)
641
+ )
642
+ ).asJava,
643
+ )
630
644
.useTrustRootCache(
631
645
() => Optional .of(new ByteArray (trustRootCert.getEncoded)),
632
646
newCache => {
@@ -693,6 +707,115 @@ class FidoMetadataDownloaderSpec
693
707
testWithHashes(Set (goodHash)) should not be null
694
708
testWithHashes(Set (badHash, goodHash)) should not be null
695
709
}
710
+
711
+ it(" The cached trust root cert must match one of the expected SHA256 hashes." ) {
712
+ val (cachedTrustRootCert, cachedCaKeypair, cachedCaName) =
713
+ makeTrustRootCert()
714
+ val (cachedRootBlobCert, cachedRootBlobKeypair, _) =
715
+ makeCert(cachedCaKeypair, cachedCaName)
716
+ val cachedRootBlobJwt = makeBlob(
717
+ List (cachedRootBlobCert),
718
+ cachedRootBlobKeypair,
719
+ LocalDate .now(),
720
+ )
721
+ val cachedRootCrls = List [CRL ](
722
+ TestAuthenticator .buildCrl(
723
+ cachedCaName,
724
+ cachedCaKeypair.getPrivate,
725
+ " SHA256withECDSA" ,
726
+ CertValidFrom ,
727
+ CertValidTo ,
728
+ )
729
+ )
730
+
731
+ val (downloadedTrustRootCert, downloadedCaKeypair, downloadedCaName) =
732
+ makeTrustRootCert()
733
+ val (downloadedRootBlobCert, downloadedRootBlobKeypair, _) =
734
+ makeCert(downloadedCaKeypair, downloadedCaName)
735
+ val downloadedRootBlobJwt = makeBlob(
736
+ List (downloadedRootBlobCert),
737
+ downloadedRootBlobKeypair,
738
+ LocalDate .now(),
739
+ )
740
+ val downloadedRootCrls = List [CRL ](
741
+ TestAuthenticator .buildCrl(
742
+ downloadedCaName,
743
+ downloadedCaKeypair.getPrivate,
744
+ " SHA256withECDSA" ,
745
+ CertValidFrom ,
746
+ CertValidTo ,
747
+ )
748
+ )
749
+
750
+ val (server, serverUrl, httpsCert) =
751
+ makeHttpServer(
752
+ " /trust-root.der" ,
753
+ downloadedTrustRootCert.getEncoded,
754
+ )
755
+ startServer(server)
756
+
757
+ def testWithHashes (
758
+ hashes : Set [ByteArray ],
759
+ blobJwt : String ,
760
+ crls : List [CRL ],
761
+ ): (MetadataBLOB , Option [ByteArray ]) = {
762
+ var writtenCache : Option [ByteArray ] = None
763
+
764
+ val blob = load(
765
+ FidoMetadataDownloader
766
+ .builder()
767
+ .expectLegalHeader(
768
+ " Kom ihåg att du aldrig får snyta dig i mattan!"
769
+ )
770
+ .downloadTrustRoot(
771
+ new URL (s " ${serverUrl}/trust-root.der " ),
772
+ hashes.asJava,
773
+ )
774
+ .useTrustRootCache(
775
+ () =>
776
+ Optional .of(new ByteArray (cachedTrustRootCert.getEncoded)),
777
+ downloaded => { writtenCache = Some (downloaded) },
778
+ )
779
+ .useBlob(blobJwt)
780
+ .useCrls(crls.asJava)
781
+ .trustHttpsCerts(httpsCert)
782
+ .clock(Clock .fixed(CertValidFrom , ZoneOffset .UTC ))
783
+ .build()
784
+ )
785
+
786
+ (blob, writtenCache)
787
+ }
788
+
789
+ {
790
+ val (blob, writtenCache) = testWithHashes(
791
+ Set (
792
+ TestAuthenticator .sha256(
793
+ new ByteArray (cachedTrustRootCert.getEncoded)
794
+ )
795
+ ),
796
+ cachedRootBlobJwt,
797
+ cachedRootCrls,
798
+ )
799
+ blob should not be null
800
+ writtenCache should be(None )
801
+ }
802
+
803
+ {
804
+ val (blob, writtenCache) = testWithHashes(
805
+ Set (
806
+ TestAuthenticator .sha256(
807
+ new ByteArray (downloadedTrustRootCert.getEncoded)
808
+ )
809
+ ),
810
+ downloadedRootBlobJwt,
811
+ downloadedRootCrls,
812
+ )
813
+ blob should not be null
814
+ writtenCache should be(
815
+ Some (new ByteArray (downloadedTrustRootCert.getEncoded))
816
+ )
817
+ }
818
+ }
696
819
}
697
820
698
821
describe(" 2. To validate the digital certificates used in the digital signature, the certificate revocation information MUST be available in the form of CRLs at the respective MDS CRL location e.g. More information can be found at https://fidoalliance.org/metadata/" ) {
0 commit comments