2424
2525import eu .webeid .security .exceptions .AuthTokenException ;
2626import eu .webeid .security .exceptions .UserCertificateOCSPCheckFailedException ;
27- import eu .webeid .security .validator .ocsp .*;
27+ import eu .webeid .security .util .DateAndTime ;
28+ import eu .webeid .security .validator .ocsp .DigestCalculatorImpl ;
29+ import eu .webeid .security .validator .ocsp .OcspClient ;
30+ import eu .webeid .security .validator .ocsp .OcspRequestBuilder ;
31+ import eu .webeid .security .validator .ocsp .OcspResponseValidator ;
32+ import eu .webeid .security .validator .ocsp .OcspServiceProvider ;
2833import eu .webeid .security .validator .ocsp .service .OcspService ;
2934import org .bouncycastle .asn1 .ocsp .OCSPObjectIdentifiers ;
3035import org .bouncycastle .asn1 .ocsp .OCSPResponseStatus ;
4146import org .bouncycastle .operator .OperatorCreationException ;
4247import org .slf4j .Logger ;
4348import org .slf4j .LoggerFactory ;
44- import eu .webeid .security .validator .ocsp .Digester ;
45- import eu .webeid .security .validator .ocsp .OcspClient ;
46- import eu .webeid .security .validator .ocsp .OcspRequestBuilder ;
47- import eu .webeid .security .validator .ocsp .OcspServiceProvider ;
4849
4950import java .io .IOException ;
5051import java .math .BigInteger ;
5152import java .security .Security ;
5253import java .security .cert .CertificateEncodingException ;
5354import java .security .cert .CertificateException ;
5455import java .security .cert .X509Certificate ;
56+ import java .time .Duration ;
5557import java .util .Date ;
5658import java .util .Objects ;
5759
5860public final class SubjectCertificateNotRevokedValidator {
5961
6062 private static final Logger LOG = LoggerFactory .getLogger (SubjectCertificateNotRevokedValidator .class );
61- private static final DigestCalculator DIGEST_CALCULATOR = Digester .sha1 ();
6263
6364 private final SubjectCertificateTrustedValidator trustValidator ;
6465 private final OcspClient ocspClient ;
6566 private final OcspServiceProvider ocspServiceProvider ;
67+ private final Duration allowedOcspResponseTimeSkew ;
68+ private final Duration maxOcspResponseThisUpdateAge ;
6669
6770 static {
6871 Security .addProvider (new BouncyCastleProvider ());
6972 }
7073
7174 public SubjectCertificateNotRevokedValidator (SubjectCertificateTrustedValidator trustValidator ,
7275 OcspClient ocspClient ,
73- OcspServiceProvider ocspServiceProvider ) {
76+ OcspServiceProvider ocspServiceProvider ,
77+ Duration allowedOcspResponseTimeSkew ,
78+ Duration maxOcspResponseThisUpdateAge ) {
7479 this .trustValidator = trustValidator ;
7580 this .ocspClient = ocspClient ;
7681 this .ocspServiceProvider = ocspServiceProvider ;
82+ this .allowedOcspResponseTimeSkew = allowedOcspResponseTimeSkew ;
83+ this .maxOcspResponseThisUpdateAge = maxOcspResponseThisUpdateAge ;
7784 }
7885
7986 /**
@@ -86,10 +93,6 @@ public void validateCertificateNotRevoked(X509Certificate subjectCertificate) th
8693 try {
8794 OcspService ocspService = ocspServiceProvider .getService (subjectCertificate );
8895
89- if (!ocspService .doesSupportNonce ()) {
90- LOG .debug ("Disabling OCSP nonce extension" );
91- }
92-
9396 final CertificateID certificateId = getCertificateId (subjectCertificate ,
9497 Objects .requireNonNull (trustValidator .getSubjectCertificateIssuerCertificate ()));
9598
@@ -98,6 +101,10 @@ public void validateCertificateNotRevoked(X509Certificate subjectCertificate) th
98101 .enableOcspNonce (ocspService .doesSupportNonce ())
99102 .build ();
100103
104+ if (!ocspService .doesSupportNonce ()) {
105+ LOG .debug ("Disabling OCSP nonce extension" );
106+ }
107+
101108 LOG .debug ("Sending OCSP request" );
102109 final OCSPResp response = Objects .requireNonNull (ocspClient .request (ocspService .getAccessLocation (), request ));
103110 if (response .getStatus () != OCSPResponseStatus .SUCCESSFUL ) {
@@ -156,8 +163,9 @@ private void verifyOcspResponse(BasicOCSPResp basicResponse, OcspService ocspSer
156163 // 4. The signer is currently authorized to provide a response for the
157164 // certificate in question.
158165
159- final Date producedAt = basicResponse .getProducedAt ();
160- ocspService .validateResponderCertificate (responderCert , producedAt );
166+ // Use the clock instance so that the date can be mocked in tests.
167+ final Date now = DateAndTime .DefaultClock .getInstance ().now ();
168+ ocspService .validateResponderCertificate (responderCert , now );
161169
162170 // 5. The time at which the status being indicated is known to be
163171 // correct (thisUpdate) is sufficiently recent.
@@ -166,7 +174,7 @@ private void verifyOcspResponse(BasicOCSPResp basicResponse, OcspService ocspSer
166174 // be available about the status of the certificate (nextUpdate) is
167175 // greater than the current time.
168176
169- OcspResponseValidator .validateCertificateStatusUpdateTime (certStatusResponse , producedAt );
177+ OcspResponseValidator .validateCertificateStatusUpdateTime (certStatusResponse , allowedOcspResponseTimeSkew , maxOcspResponseThisUpdateAge );
170178
171179 // Now we can accept the signed response as valid and validate the certificate status.
172180 OcspResponseValidator .validateSubjectCertificateStatus (certStatusResponse );
@@ -188,7 +196,8 @@ private static void checkNonce(OCSPReq request, BasicOCSPResp response) throws U
188196
189197 private static CertificateID getCertificateId (X509Certificate subjectCertificate , X509Certificate issuerCertificate ) throws CertificateEncodingException , IOException , OCSPException {
190198 final BigInteger serial = subjectCertificate .getSerialNumber ();
191- return new CertificateID (DIGEST_CALCULATOR ,
199+ final DigestCalculator digestCalculator = DigestCalculatorImpl .sha1 ();
200+ return new CertificateID (digestCalculator ,
192201 new X509CertificateHolder (issuerCertificate .getEncoded ()), serial );
193202 }
194203
0 commit comments