Skip to content

Commit fce60d8

Browse files
Eugene BochiloUbuntu
authored andcommitted
Cover CertificateVerification#verifyOcspCertificates with tests
DEVSIX-6099
1 parent 3578748 commit fce60d8

File tree

7 files changed

+121
-9
lines changed

7 files changed

+121
-9
lines changed

sign/src/main/java/com/itextpdf/signatures/CertificateVerification.java

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ This file is part of the iText (R) project.
4444
package com.itextpdf.signatures;
4545

4646
import com.itextpdf.commons.utils.DateTimeUtil;
47+
import com.itextpdf.signatures.logs.SignLogMessageConstant;
4748
import org.bouncycastle.cert.ocsp.BasicOCSPResp;
4849
import org.bouncycastle.tsp.TimeStampToken;
4950
import org.slf4j.Logger;
@@ -67,7 +68,7 @@ public class CertificateVerification {
6768
/**
6869
* The Logger instance.
6970
*/
70-
private static final Logger LOGGER = LoggerFactory.getLogger(CrlClientOnline.class);
71+
private static final Logger LOGGER = LoggerFactory.getLogger(CertificateVerification.class);
7172

7273
/**
7374
* Verifies a single certificate for the current date.
@@ -216,17 +217,18 @@ public static boolean verifyOcspCertificates(BasicOCSPResp ocsp, KeyStore keysto
216217
try {
217218
for (X509Certificate certStoreX509 : SignUtils.getCertificates(keystore)) {
218219
try {
219-
return SignUtils.isSignatureValid(ocsp, certStoreX509, provider);
220+
if (SignUtils.isSignatureValid(ocsp, certStoreX509, provider)) {
221+
return true;
222+
}
220223
} catch (Exception ex) {
221224
exceptionsThrown.add(ex);
222225
}
223226
}
224227
} catch (Exception e) {
225228
exceptionsThrown.add(e);
226229
}
227-
for (Exception ex : exceptionsThrown) {
228-
LOGGER.error(ex.getMessage(), ex);
229-
}
230+
231+
logExceptionMessages(exceptionsThrown);
230232
return false;
231233
}
232234

@@ -250,13 +252,18 @@ public static boolean verifyTimestampCertificates(TimeStampToken ts, KeyStore ke
250252
}
251253
}
252254
} catch (Exception e) {
253-
LOGGER.error("Unexpected exception was thrown during keystore processing", e);
255+
exceptionsThrown.add(e);
254256
}
255257

258+
logExceptionMessages(exceptionsThrown);
259+
return false;
260+
}
261+
262+
private static void logExceptionMessages(List<Exception> exceptionsThrown) {
256263
for (Exception ex : exceptionsThrown) {
257-
LOGGER.error(ex.getMessage(), ex);
264+
LOGGER.error(ex.getMessage() == null ?
265+
SignLogMessageConstant.EXCEPTION_WITHOUT_MESSAGE : ex.getMessage(), ex);
258266
}
259-
return false;
260267
}
261268

262269
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.itextpdf.signatures.logs;
2+
3+
/**
4+
* Class which contains constants to be used in logging inside sign module.
5+
*/
6+
public final class SignLogMessageConstant {
7+
8+
public static final String EXCEPTION_WITHOUT_MESSAGE =
9+
"Unexpected exception without message was thrown during keystore processing";
10+
11+
private SignLogMessageConstant() {
12+
// Private constructor will prevent the instantiation of this class directly
13+
}
14+
}

sign/src/test/java/com/itextpdf/signatures/verify/CertificateVerificationClassTest.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ This file is part of the iText (R) project.
7575

7676
@Category(UnitTest.class)
7777
public class CertificateVerificationClassTest extends ExtendedITextTest {
78+
79+
// Such messageTemplate is equal to any log message. This is required for porting reasons.
80+
private static final String ANY_LOG_MESSAGE = "{0}";
81+
7882
private static final String certsSrc = "./src/test/resources/com/itextpdf/signatures/certs/";
7983
private static final char[] password = "testpass".toCharArray();
8084

@@ -122,7 +126,7 @@ public void timestampCertificateAndKeyStoreDoNotCorrespondTest() throws Exceptio
122126
}
123127

124128
@Test
125-
@LogMessages(messages = @LogMessage(messageTemplate = "Unexpected exception was thrown during keystore processing"))
129+
@LogMessages(messages = @LogMessage(messageTemplate = ANY_LOG_MESSAGE))
126130
public void keyStoreWithoutCertificatesTest() throws Exception {
127131
String tsaCertFileName = certsSrc + "tsCertRsa.p12";
128132

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package com.itextpdf.signatures.verify;
2+
3+
import com.itextpdf.signatures.CertificateVerification;
4+
import com.itextpdf.signatures.testutils.client.TestOcspClient;
5+
import com.itextpdf.test.ExtendedITextTest;
6+
import com.itextpdf.test.annotations.LogMessage;
7+
import com.itextpdf.test.annotations.LogMessages;
8+
import com.itextpdf.test.annotations.type.UnitTest;
9+
import com.itextpdf.test.signutils.Pkcs12FileHelper;
10+
import org.bouncycastle.asn1.ASN1Primitive;
11+
import org.bouncycastle.asn1.ocsp.BasicOCSPResponse;
12+
import org.bouncycastle.cert.ocsp.BasicOCSPResp;
13+
import org.bouncycastle.jce.provider.BouncyCastleProvider;
14+
import org.junit.Assert;
15+
import org.junit.BeforeClass;
16+
import org.junit.Test;
17+
import org.junit.experimental.categories.Category;
18+
19+
import java.security.PrivateKey;
20+
import java.security.Security;
21+
import java.security.cert.X509Certificate;
22+
23+
@Category(UnitTest.class)
24+
public class OcspCertificateVerificationTest extends ExtendedITextTest {
25+
26+
// Such messageTemplate is equal to any log message. This is required for porting reasons.
27+
private static final String ANY_LOG_MESSAGE = "{0}";
28+
29+
private static final String ocspCertsSrc = "./src/test/resources/com/itextpdf/signatures/verify/OcspCertificateVerificationTest/";
30+
31+
private static final String rootOcspCert = ocspCertsSrc + "ocspRootRsa.p12";
32+
private static final String signOcspCert = ocspCertsSrc + "ocspSignRsa.p12";
33+
private static final String notOcspAndOcspCert = ocspCertsSrc + "notOcspAndOcspCertificates.p12";
34+
35+
private static final char[] password = "testpass".toCharArray();
36+
private static final String ocspServiceUrl = "http://localhost:9000/demo/ocsp/ocsp-service";
37+
38+
private static X509Certificate checkCert;
39+
private static X509Certificate rootCert;
40+
41+
@BeforeClass
42+
public static void before() throws Exception {
43+
Security.addProvider(new BouncyCastleProvider());
44+
checkCert = (X509Certificate) Pkcs12FileHelper.readFirstChain(signOcspCert, password)[0];
45+
rootCert = (X509Certificate) Pkcs12FileHelper.readFirstChain(rootOcspCert, password)[0];
46+
}
47+
48+
@Test
49+
public void keyStoreWithRootOcspCertificateTest() throws Exception {
50+
BasicOCSPResp response = getOcspResponse();
51+
52+
Assert.assertTrue(CertificateVerification.verifyOcspCertificates(
53+
response, Pkcs12FileHelper.initStore(rootOcspCert, password), null));
54+
}
55+
56+
@Test
57+
public void keyStoreWithSignOcspCertificateTest() throws Exception {
58+
BasicOCSPResp response = getOcspResponse();
59+
60+
Assert.assertFalse(CertificateVerification.verifyOcspCertificates(
61+
response, Pkcs12FileHelper.initStore(signOcspCert, password), null));
62+
}
63+
64+
@Test
65+
public void keyStoreWithNotOcspAndOcspCertificatesTest() throws Exception {
66+
BasicOCSPResp response = getOcspResponse();
67+
68+
Assert.assertTrue(CertificateVerification.verifyOcspCertificates(
69+
response, Pkcs12FileHelper.initStore(notOcspAndOcspCert, password), null));
70+
}
71+
72+
@Test
73+
@LogMessages(messages = @LogMessage(messageTemplate = ANY_LOG_MESSAGE))
74+
public void keyStoreWithNotOcspCertificateTest() throws Exception {
75+
Assert.assertFalse(CertificateVerification.verifyOcspCertificates(
76+
null, Pkcs12FileHelper.initStore(signOcspCert, password), null));
77+
}
78+
79+
private static BasicOCSPResp getOcspResponse() throws Exception {
80+
TestOcspClient testClient = new TestOcspClient();
81+
PrivateKey key = Pkcs12FileHelper.readFirstKey(rootOcspCert, password, password);
82+
testClient.addBuilderForCertIssuer(rootCert, key);
83+
byte[] ocspResponseBytes = testClient.getEncoded(checkCert, rootCert, ocspServiceUrl);
84+
ASN1Primitive var2 = ASN1Primitive.fromByteArray(ocspResponseBytes);
85+
return new BasicOCSPResp(BasicOCSPResponse.getInstance(var2));
86+
}
87+
}

0 commit comments

Comments
 (0)