Skip to content

Commit fa53e4c

Browse files
committed
NFC-128 Add OCSP tests for Belgian and Finnish test cards
1 parent 2f4115a commit fa53e4c

5 files changed

Lines changed: 86 additions & 0 deletions

File tree

src/test/java/eu/webeid/security/testutil/AuthTokenValidators.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,26 @@ public static AuthTokenValidator getAuthTokenValidatorForFinnishIdCard() throws
108108
);
109109
}
110110

111+
public static AuthTokenValidator getAuthTokenValidatorForBelgianIdCardWithOcspCheck(OcspClient ocspClient) throws CertificateException, IOException, JceException {
112+
return getAuthTokenValidatorBuilder(
113+
"https://47f0-46-131-86-189.ngrok-free.app",
114+
CertificateLoader.loadCertificatesFromResources("eID TEST EC Citizen CA.cer"))
115+
// The recorded OCSP response used in tests was created without a nonce.
116+
.withNonceDisabledOcspUrls(URI.create("http://eiddevcards.zetescards.be:8888"))
117+
.withOcspClient(ocspClient)
118+
.build();
119+
}
120+
121+
public static AuthTokenValidator getAuthTokenValidatorForFinnishIdCardWithOcspCheck(OcspClient ocspClient) throws CertificateException, IOException, JceException {
122+
return getAuthTokenValidatorBuilder(
123+
"https://47f0-46-131-86-189.ngrok-free.app",
124+
CertificateLoader.loadCertificatesFromResources("DVV TEST Certificates - G5E.crt", "VRK TEST CA for Test Purposes - G4.crt"))
125+
// The recorded OCSP response used in tests was created without a nonce.
126+
.withNonceDisabledOcspUrls(URI.create("http://ocsptest.fineid.fi/dvvtp5ec"))
127+
.withOcspClient(ocspClient)
128+
.build();
129+
}
130+
111131
public static AuthTokenValidatorBuilder getDefaultAuthTokenValidatorBuilder() throws CertificateException, IOException {
112132
return getAuthTokenValidatorBuilder(TOKEN_ORIGIN_URL, getCACertificates());
113133
}

src/test/java/eu/webeid/security/validator/AuthTokenCertificateBelgianIdCardTest.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,18 @@
2727
import eu.webeid.security.testutil.AbstractTestWithValidator;
2828
import eu.webeid.security.testutil.AuthTokenValidators;
2929
import eu.webeid.security.util.DateAndTime;
30+
import eu.webeid.security.validator.ocsp.OcspClient;
31+
import org.bouncycastle.cert.ocsp.OCSPResp;
3032
import org.junit.jupiter.api.AfterEach;
3133
import org.junit.jupiter.api.BeforeEach;
34+
import org.junit.jupiter.api.Disabled;
3235
import org.junit.jupiter.api.Test;
3336
import org.mockito.MockedStatic;
3437

3538
import java.io.IOException;
39+
import java.io.InputStream;
3640
import java.security.cert.CertificateException;
41+
import java.util.Objects;
3742

3843
import static eu.webeid.security.testutil.DateMocker.mockDate;
3944
import static org.assertj.core.api.Assertions.assertThatCode;
@@ -95,4 +100,32 @@ void whenIdCardWithRSASignatureCertificateIsValidated_thenValidationSucceeds() t
95100
.doesNotThrowAnyException();
96101
}
97102

103+
@Disabled("""
104+
Disabled because the certificate ID equality check in SubjectCertificateNotRevokedValidator rejects the OCSP
105+
response: CertificateID.equals() compares the complete ASN.1 structure, which treats absent and explicit NULL SHA-1
106+
AlgorithmIdentifier parameters as different. CertID.equals() treats those forms as equivalent while still comparing
107+
the algorithm identifier, issuer hashes and certificate serial number.""")
108+
@Test
109+
void whenIdCardIsValidatedWithAiaOcspCheck_thenDelegatedResponderIsAuthorizedAndValidationSucceeds() throws AuthTokenException, CertificateException, IOException {
110+
// The OCSP response was recorded from the card's AIA OCSP responder at http://eiddevcards.zetescards.be:8888
111+
// on 2026-07-02. Its responder certificate is issued by eID TEST EC Citizen CA, the issuer of the
112+
// authentication certificate, so the RFC 6960 delegated-responder authorization check in AiaOcspService
113+
// must accept it. The clock is set to the recording time as the response thisUpdate age is limited.
114+
mockDate("2026-07-02T08:39:30Z", mockedClock);
115+
final OcspClient recordedResponseClient = (url, request) ->
116+
new OCSPResp(getOcspResponseBytesFromResources("ocsp_response_belgian_test_id_card.der"));
117+
final AuthTokenValidator validator = AuthTokenValidators.getAuthTokenValidatorForBelgianIdCardWithOcspCheck(recordedResponseClient);
118+
final WebEidAuthToken token = validator.parse(BELGIAN_TEST_ID_CARD_AUTH_TOKEN_ECC);
119+
120+
assertThatCode(() -> validator
121+
.validate(token, "iMeEwP2cgUINY2XoO/lqEpOUn7z/ysHRqGXkGKC4VXE="))
122+
.doesNotThrowAnyException();
123+
}
124+
125+
private static byte[] getOcspResponseBytesFromResources(String resource) throws IOException {
126+
try (final InputStream resourceAsStream = ClassLoader.getSystemResourceAsStream(resource)) {
127+
return Objects.requireNonNull(resourceAsStream).readAllBytes();
128+
}
129+
}
130+
98131
}

src/test/java/eu/webeid/security/validator/AuthTokenCertificateFinnishIdCardTest.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,18 @@
2727
import eu.webeid.security.testutil.AbstractTestWithValidator;
2828
import eu.webeid.security.testutil.AuthTokenValidators;
2929
import eu.webeid.security.util.DateAndTime;
30+
import eu.webeid.security.validator.ocsp.OcspClient;
31+
import org.bouncycastle.cert.ocsp.OCSPResp;
3032
import org.junit.jupiter.api.AfterEach;
3133
import org.junit.jupiter.api.BeforeEach;
34+
import org.junit.jupiter.api.Disabled;
3235
import org.junit.jupiter.api.Test;
3336
import org.mockito.MockedStatic;
3437

3538
import java.io.IOException;
39+
import java.io.InputStream;
3640
import java.security.cert.CertificateException;
41+
import java.util.Objects;
3742

3843
import static eu.webeid.security.testutil.DateMocker.mockDate;
3944
import static org.assertj.core.api.Assertions.assertThatCode;
@@ -96,4 +101,32 @@ void whenIdCardSignatureCertificateWithG4RootCertificateIsValidated_thenValidati
96101
.doesNotThrowAnyException();
97102
}
98103

104+
@Disabled("""
105+
Disabled because the certificate ID equality check in SubjectCertificateNotRevokedValidator rejects the OCSP
106+
response: CertificateID.equals() compares the complete ASN.1 structure, which treats absent and explicit NULL SHA-1
107+
AlgorithmIdentifier parameters as different. CertID.equals() treats those forms as equivalent while still comparing
108+
the algorithm identifier, issuer hashes and certificate serial number.""")
109+
@Test
110+
void whenIdCardIsValidatedWithAiaOcspCheck_thenDelegatedResponderIsAuthorizedAndValidationSucceeds() throws AuthTokenException, CertificateException, IOException {
111+
// The OCSP response was recorded from the card's AIA OCSP responder at http://ocsptest.fineid.fi/dvvtp5ec
112+
// on 2026-07-02. Its responder certificate is issued by DVV TEST Certificates - G5E, the issuer of the
113+
// authentication certificate, so the RFC 6960 delegated-responder authorization check in AiaOcspService
114+
// must accept it. The clock is set to the recording time as the response thisUpdate age is limited.
115+
mockDate("2026-07-02T08:39:30Z", mockedClock);
116+
final OcspClient recordedResponseClient = (url, request) ->
117+
new OCSPResp(getOcspResponseBytesFromResources("ocsp_response_finnish_test_id_card.der"));
118+
final AuthTokenValidator validator = AuthTokenValidators.getAuthTokenValidatorForFinnishIdCardWithOcspCheck(recordedResponseClient);
119+
final WebEidAuthToken token = validator.parse(FINNISH_TEST_ID_CARD_BACKMAN_JUHANI_AUTH_TOKEN);
120+
121+
assertThatCode(() -> validator
122+
.validate(token, "x9qZDRO/ao2zprt3Z0bkW4CvvE/gALFtUIf3tcC0XxY="))
123+
.doesNotThrowAnyException();
124+
}
125+
126+
private static byte[] getOcspResponseBytesFromResources(String resource) throws IOException {
127+
try (final InputStream resourceAsStream = ClassLoader.getSystemResourceAsStream(resource)) {
128+
return Objects.requireNonNull(resourceAsStream).readAllBytes();
129+
}
130+
}
131+
99132
}
1.98 KB
Binary file not shown.
2.23 KB
Binary file not shown.

0 commit comments

Comments
 (0)