Skip to content

Commit 259de2e

Browse files
authored
BAEL-6700 - Check if Certificate is Self-Signed or CA Signed with Java (#14628)
* BAEL-6700 - Check if Certificate is Self-Signed or CA Signed with Java * Added new module to parent pom * Update test method names
1 parent add56cc commit 259de2e

7 files changed

Lines changed: 151 additions & 0 deletions

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
## Core Java Security
2+
3+
This module contains articles about core Java Security
4+
5+
### Relevant Articles:
6+
7+
- More articles: [[<-- prev]](/core-java-modules/core-java-security-3)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
<artifactId>core-java-security-4</artifactId>
7+
<name>core-java-security-4</name>
8+
<packaging>jar</packaging>
9+
10+
<parent>
11+
<groupId>com.baeldung.core-java-modules</groupId>
12+
<artifactId>core-java-modules</artifactId>
13+
<version>0.0.1-SNAPSHOT</version>
14+
</parent>
15+
16+
</project>
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package com.baeldung.certificate;
2+
3+
import java.security.KeyStore;
4+
import java.security.KeyStoreException;
5+
import java.security.cert.Certificate;
6+
import java.security.cert.X509Certificate;
7+
import java.util.Enumeration;
8+
9+
public class RootCertificateUtil {
10+
11+
private RootCertificateUtil() {
12+
}
13+
14+
public static X509Certificate getRootCertificate(X509Certificate endEntityCertificate, KeyStore trustStore)
15+
throws Exception {
16+
X509Certificate issuerCertificate = findIssuerCertificate(endEntityCertificate, trustStore);
17+
if (issuerCertificate != null) {
18+
if (isRoot(issuerCertificate)) {
19+
return issuerCertificate;
20+
} else {
21+
return getRootCertificate(issuerCertificate, trustStore);
22+
}
23+
}
24+
return null;
25+
}
26+
27+
private static X509Certificate findIssuerCertificate(X509Certificate certificate, KeyStore trustStore)
28+
throws KeyStoreException {
29+
Enumeration<String> aliases = trustStore.aliases();
30+
while (aliases.hasMoreElements()) {
31+
String alias = aliases.nextElement();
32+
Certificate cert = trustStore.getCertificate(alias);
33+
if (cert instanceof X509Certificate) {
34+
X509Certificate x509Cert = (X509Certificate) cert;
35+
if (x509Cert.getSubjectX500Principal().equals(certificate.getIssuerX500Principal())) {
36+
return x509Cert;
37+
}
38+
}
39+
}
40+
return null;
41+
}
42+
43+
private static boolean isRoot(X509Certificate certificate) {
44+
try {
45+
certificate.verify(certificate.getPublicKey());
46+
return certificate.getKeyUsage() != null && certificate.getKeyUsage()[5];
47+
} catch (Exception e) {
48+
return false;
49+
}
50+
}
51+
}
Binary file not shown.
Binary file not shown.
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package com.baeldung.certificate;
2+
3+
import org.junit.jupiter.api.BeforeEach;
4+
import org.junit.jupiter.api.Test;
5+
6+
import java.security.KeyStore;
7+
import java.security.SignatureException;
8+
import java.security.cert.X509Certificate;
9+
10+
import static com.baeldung.certificate.RootCertificateUtil.getRootCertificate;
11+
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
12+
import static org.junit.jupiter.api.Assertions.assertEquals;
13+
import static org.junit.jupiter.api.Assertions.assertNotEquals;
14+
import static org.junit.jupiter.api.Assertions.assertNotNull;
15+
import static org.junit.jupiter.api.Assertions.assertNull;
16+
import static org.junit.jupiter.api.Assertions.assertThrows;
17+
import static org.junit.jupiter.api.Assertions.assertTrue;
18+
19+
class SignedCertificateUnitTest {
20+
21+
private KeyStore keyStore;
22+
23+
private KeyStore trustStore;
24+
25+
@BeforeEach
26+
public void setUp() throws Exception {
27+
char[] passwd = "changeit".toCharArray();
28+
keyStore = KeyStore.getInstance("JKS");
29+
keyStore.load(this.getClass().getClassLoader().getResourceAsStream("keystore.jks"), passwd);
30+
trustStore = KeyStore.getInstance("JKS");
31+
trustStore.load(this.getClass().getClassLoader().getResourceAsStream("truststore.jks"), passwd);
32+
}
33+
34+
@Test
35+
void whenCertificateIsSelfSigned_thenSubjectIsEqualToIssuer() throws Exception {
36+
X509Certificate certificate = (X509Certificate) keyStore.getCertificate("selfsigned");
37+
assertEquals(certificate.getSubjectDN(), certificate.getIssuerDN());
38+
}
39+
40+
@Test
41+
void whenCertificateIsSelfSigned_thenItCanBeVerifiedWithItsOwnPublicKey() throws Exception {
42+
X509Certificate certificate = (X509Certificate) keyStore.getCertificate("selfsigned");
43+
assertDoesNotThrow(() -> certificate.verify(certificate.getPublicKey()));
44+
}
45+
46+
@Test
47+
void whenCertificateIsCASigned_thenItCantBeVerifiedWithItsOwnPublicKey() throws Exception {
48+
X509Certificate certificate = (X509Certificate) keyStore.getCertificate("baeldung");
49+
assertThrows(SignatureException.class, () -> certificate.verify(certificate.getPublicKey()));
50+
}
51+
52+
@Test
53+
void whenCertificateIsCASigned_thenRootCanBeFoundInTruststore() throws Exception {
54+
X509Certificate endEntityCertificate = (X509Certificate) keyStore.getCertificate("baeldung");
55+
X509Certificate rootCertificate = getRootCertificate(endEntityCertificate, trustStore);
56+
assertNotNull(rootCertificate);
57+
}
58+
59+
@Test
60+
void whenCertificateIsCA_thenItCanBeUsedToSignOtherCertificates() throws Exception {
61+
X509Certificate certificate = (X509Certificate) keyStore.getCertificate("cloudflare");
62+
assertTrue(certificate.getKeyUsage()[5]);
63+
}
64+
65+
@Test
66+
void whenCertificateIsCA_thenBasicConstrainsReturnsZeroOrGreaterThanZero() throws Exception {
67+
X509Certificate certificate = (X509Certificate) keyStore.getCertificate("cloudflare");
68+
assertNotEquals(-1, certificate.getBasicConstraints());
69+
}
70+
71+
@Test
72+
void whenCertificateIsSelfSigned_thenItCantBeUsedToSignOtherCertificates() throws Exception {
73+
X509Certificate certificate = (X509Certificate) keyStore.getCertificate("selfsigned");
74+
assertNull(certificate.getKeyUsage());
75+
}
76+
}

core-java-modules/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@
127127
<module>core-java-scanner</module>
128128
<module>core-java-security-2</module>
129129
<module>core-java-security-3</module>
130+
<module>core-java-security-4</module>
130131
<module>core-java-security-algorithms</module>
131132
<module>core-java-streams</module>
132133
<module>core-java-streams-3</module>

0 commit comments

Comments
 (0)