@@ -81,6 +81,7 @@ import org.bouncycastle.asn1.x509.Extension
81
81
import org .bouncycastle .asn1 .x509 .GeneralName
82
82
import org .bouncycastle .asn1 .x509 .GeneralNamesBuilder
83
83
import org .bouncycastle .cert .jcajce .JcaX500NameUtil
84
+ import org .bouncycastle .jce .provider .BouncyCastleProvider
84
85
import org .junit .runner .RunWith
85
86
import org .mockito .Mockito
86
87
import org .scalacheck .Arbitrary .arbitrary
@@ -98,10 +99,12 @@ import java.security.KeyFactory
98
99
import java .security .KeyPair
99
100
import java .security .MessageDigest
100
101
import java .security .PrivateKey
102
+ import java .security .Security
101
103
import java .security .SignatureException
102
104
import java .security .cert .CRL
103
105
import java .security .cert .CertStore
104
106
import java .security .cert .CollectionCertStoreParameters
107
+ import java .security .cert .PolicyNode
105
108
import java .security .cert .X509Certificate
106
109
import java .security .interfaces .ECPublicKey
107
110
import java .security .interfaces .RSAPublicKey
@@ -111,6 +114,7 @@ import java.time.ZoneOffset
111
114
import java .util
112
115
import java .util .Collections
113
116
import java .util .Optional
117
+ import java .util .function .Predicate
114
118
import javax .security .auth .x500 .X500Principal
115
119
import scala .jdk .CollectionConverters ._
116
120
import scala .jdk .OptionConverters .RichOption
@@ -193,6 +197,7 @@ class RelyingPartyRegistrationSpec
193
197
trustedCert : X509Certificate ,
194
198
crls : Option [Set [CRL ]] = None ,
195
199
enableRevocationChecking : Boolean = true ,
200
+ policyTreeValidator : Option [Predicate [PolicyNode ]] = None ,
196
201
): AttestationTrustSource =
197
202
(_ : util.List [X509Certificate ], _ : Optional [ByteArray ]) => {
198
203
TrustRootsResult
@@ -209,6 +214,7 @@ class RelyingPartyRegistrationSpec
209
214
.orNull
210
215
)
211
216
.enableRevocationChecking(enableRevocationChecking)
217
+ .policyTreeValidator(policyTreeValidator.orNull)
212
218
.build()
213
219
}
214
220
@@ -2088,6 +2094,7 @@ class RelyingPartyRegistrationSpec
2088
2094
trustSourceWith(
2089
2095
testData.attestationRootCertificate.get,
2090
2096
enableRevocationChecking = false ,
2097
+ policyTreeValidator = Some (_ => true ),
2091
2098
)
2092
2099
),
2093
2100
)
@@ -3364,6 +3371,7 @@ class RelyingPartyRegistrationSpec
3364
3371
trustedRootCert : Option [X509Certificate ] = None ,
3365
3372
enableRevocationChecking : Boolean = true ,
3366
3373
origins : Option [Set [String ]] = None ,
3374
+ policyTreeValidator : Option [Predicate [PolicyNode ]] = None ,
3367
3375
): Unit = {
3368
3376
it(" is rejected if untrusted attestation is not allowed and the trust source does not trust it." ) {
3369
3377
val steps = finishRegistration(
@@ -3418,6 +3426,7 @@ class RelyingPartyRegistrationSpec
3418
3426
)
3419
3427
}),
3420
3428
enableRevocationChecking = enableRevocationChecking,
3429
+ policyTreeValidator = policyTreeValidator,
3421
3430
)
3422
3431
)
3423
3432
val steps = finishRegistration(
@@ -3469,6 +3478,7 @@ class RelyingPartyRegistrationSpec
3469
3478
.trustRoots(Collections .emptySet())
3470
3479
.certStore(certStore)
3471
3480
.enableRevocationChecking(enableRevocationChecking)
3481
+ .policyTreeValidator(policyTreeValidator.orNull)
3472
3482
.build()
3473
3483
}
3474
3484
val steps = finishRegistration(
@@ -3497,6 +3507,7 @@ class RelyingPartyRegistrationSpec
3497
3507
.trustRoots(Collections .singleton(rootCert))
3498
3508
.certStore(certStore)
3499
3509
.enableRevocationChecking(enableRevocationChecking)
3510
+ .policyTreeValidator(policyTreeValidator.orNull)
3500
3511
.build()
3501
3512
}
3502
3513
val steps = finishRegistration(
@@ -3573,8 +3584,67 @@ class RelyingPartyRegistrationSpec
3573
3584
origins = Some (Set (testData.clientData.getOrigin)),
3574
3585
trustedRootCert = Some (testData.attestationRootCertificate.get),
3575
3586
enableRevocationChecking = false ,
3587
+ policyTreeValidator = Some (_ => true ),
3576
3588
)
3577
3589
}
3590
+
3591
+ describe(" Critical certificate policy extensions" ) {
3592
+ def init (
3593
+ policyTreeValidator : Option [Predicate [PolicyNode ]]
3594
+ ): FinishRegistrationSteps # Step21 = {
3595
+ val testData = RegistrationTestData .Tpm .RealExample
3596
+ val clock = Clock .fixed(
3597
+ Instant .parse(" 2022-08-25T16:00:00Z" ),
3598
+ ZoneOffset .UTC ,
3599
+ )
3600
+ val steps = finishRegistration(
3601
+ allowUntrustedAttestation = false ,
3602
+ origins = Some (Set (testData.clientData.getOrigin)),
3603
+ testData = testData,
3604
+ attestationTrustSource = Some (
3605
+ trustSourceWith(
3606
+ testData.attestationRootCertificate.get,
3607
+ enableRevocationChecking = false ,
3608
+ policyTreeValidator = policyTreeValidator,
3609
+ )
3610
+ ),
3611
+ clock = clock,
3612
+ )
3613
+
3614
+ steps.begin.next.next.next.next.next.next.next.next.next.next.next.next.next.next
3615
+ }
3616
+
3617
+ it(" are rejected if no policy tree validator is set." ) {
3618
+ // BouncyCastle provider does not reject critical policy extensions
3619
+ // TODO Mark test as ignored instead of just skipping (assume() and cancel() currently break pitest)
3620
+ if (
3621
+ ! Security .getProviders
3622
+ .exists(p => p.isInstanceOf [BouncyCastleProvider ])
3623
+ ) {
3624
+ val step = init(policyTreeValidator = None )
3625
+
3626
+ step.validations shouldBe a[Failure [_]]
3627
+ step.attestationTrusted should be(false )
3628
+ step.tryNext shouldBe a[Failure [_]]
3629
+ }
3630
+ }
3631
+
3632
+ it(" are accepted if a policy tree validator is set and accepts the policy tree." ) {
3633
+ val step = init(policyTreeValidator = Some (_ => true ))
3634
+
3635
+ step.validations shouldBe a[Success [_]]
3636
+ step.attestationTrusted should be(true )
3637
+ step.tryNext shouldBe a[Success [_]]
3638
+ }
3639
+
3640
+ it(" are rejected if a policy tree validator is set and does not accept the policy tree." ) {
3641
+ val step = init(policyTreeValidator = Some (_ => false ))
3642
+
3643
+ step.validations shouldBe a[Failure [_]]
3644
+ step.attestationTrusted should be(false )
3645
+ step.tryNext shouldBe a[Failure [_]]
3646
+ }
3647
+ }
3578
3648
}
3579
3649
}
3580
3650
@@ -4413,6 +4483,7 @@ class RelyingPartyRegistrationSpec
4413
4483
trustSourceWith(
4414
4484
testData.attestationRootCertificate.get,
4415
4485
enableRevocationChecking = false ,
4486
+ policyTreeValidator = Some (_ => true ),
4416
4487
)
4417
4488
),
4418
4489
credentialRepository = Helpers .CredentialRepository .empty,
0 commit comments