2929import java .security .Security ;
3030import java .security .cert .X509Certificate ;
3131import java .util .Arrays ;
32+ import java .util .List ;
33+
3234import org .apache .commons .io .FileUtils ;
3335import org .bouncycastle .asn1 .x500 .X500NameBuilder ;
3436import org .bouncycastle .asn1 .x500 .style .BCStyle ;
@@ -48,7 +50,7 @@ public class X509TestContext {
4850 private final X509KeyType trustStoreKeyType ;
4951 private final KeyPair trustStoreKeyPair ;
5052 private final long trustStoreCertExpirationMillis ;
51- private final X509Certificate trustStoreCertificate ;
53+ private final List < X509Certificate > trustStoreCertificates ;
5254 private final String trustStorePassword ;
5355 private File trustStoreJksFile ;
5456 private File trustStorePemFile ;
@@ -99,11 +101,18 @@ private X509TestContext(File tempDir, KeyPair trustStoreKeyPair, long trustStore
99101
100102 X500NameBuilder caNameBuilder = new X500NameBuilder (BCStyle .INSTANCE );
101103 caNameBuilder .addRDN (BCStyle .CN , MethodHandles .lookup ().lookupClass ().getCanonicalName () + " Root CA" );
102- trustStoreCertificate = X509TestHelpers .newSelfSignedCACert (caNameBuilder .build (), trustStoreKeyPair , trustStoreCertExpirationMillis );
104+ // Create two CA certs to test multiple certs in PEM bundles.
105+ // Use same subject name to simulate multiple CA certs from the same CA.
106+ trustStoreCertificates = Arrays .asList (
107+ X509TestHelpers .newSelfSignedCACert (caNameBuilder .build (), trustStoreKeyPair ,
108+ trustStoreCertExpirationMillis ),
109+ X509TestHelpers .newSelfSignedCACert (caNameBuilder .build (), trustStoreKeyPair ,
110+ trustStoreCertExpirationMillis )
111+ );
103112
104113 X500NameBuilder nameBuilder = new X500NameBuilder (BCStyle .INSTANCE );
105114 nameBuilder .addRDN (BCStyle .CN , MethodHandles .lookup ().lookupClass ().getCanonicalName () + " Zookeeper Test" );
106- keyStoreCertificate = X509TestHelpers .newCert (trustStoreCertificate , trustStoreKeyPair , nameBuilder .build (), keyStoreKeyPair .getPublic (), keyStoreCertExpirationMillis );
115+ keyStoreCertificate = X509TestHelpers .newCert (trustStoreCertificates . get ( 0 ) , trustStoreKeyPair , nameBuilder .build (), keyStoreKeyPair .getPublic (), keyStoreCertExpirationMillis );
107116 trustStorePkcs12File = trustStorePemFile = trustStoreJksFile = null ;
108117 keyStorePkcs12File = keyStorePemFile = keyStoreJksFile = null ;
109118
@@ -139,8 +148,8 @@ public long getTrustStoreCertExpirationMillis() {
139148 return trustStoreCertExpirationMillis ;
140149 }
141150
142- public X509Certificate getTrustStoreCertificate () {
143- return trustStoreCertificate ;
151+ public X509Certificate getTrustStoreCertificates () {
152+ return trustStoreCertificates . get ( 0 ) ;
144153 }
145154
146155 public String getTrustStorePassword () {
@@ -159,7 +168,7 @@ public File getTrustStoreFile(KeyStoreFileType storeFileType) throws IOException
159168 case JKS :
160169 return getTrustStoreJksFile ();
161170 case PEM :
162- return getTrustStorePemFile ();
171+ return getTrustStorePemBundleFile ();
163172 case PKCS12 :
164173 return getTrustStorePkcs12File ();
165174 case BCFKS :
@@ -177,7 +186,7 @@ private File getTrustStoreJksFile() throws IOException {
177186 File trustStoreJksFile = File .createTempFile (TRUST_STORE_PREFIX , KeyStoreFileType .JKS .getDefaultFileExtension (), tempDir );
178187 trustStoreJksFile .deleteOnExit ();
179188 try (final FileOutputStream trustStoreOutputStream = new FileOutputStream (trustStoreJksFile )) {
180- byte [] bytes = X509TestHelpers .certToJavaTrustStoreBytes (trustStoreCertificate , trustStorePassword );
189+ byte [] bytes = X509TestHelpers .certToJavaTrustStoreBytes (trustStoreCertificates . get ( 0 ) , trustStorePassword );
181190 trustStoreOutputStream .write (bytes );
182191 trustStoreOutputStream .flush ();
183192 } catch (GeneralSecurityException e ) {
@@ -188,11 +197,13 @@ private File getTrustStoreJksFile() throws IOException {
188197 return trustStoreJksFile ;
189198 }
190199
191- private File getTrustStorePemFile () throws IOException {
200+ private File getTrustStorePemBundleFile () throws IOException {
192201 if (trustStorePemFile == null ) {
193202 File trustStorePemFile = File .createTempFile (TRUST_STORE_PREFIX , KeyStoreFileType .PEM .getDefaultFileExtension (), tempDir );
194203 trustStorePemFile .deleteOnExit ();
195- FileUtils .writeStringToFile (trustStorePemFile , X509TestHelpers .pemEncodeX509Certificate (trustStoreCertificate ), StandardCharsets .US_ASCII , false );
204+ for (X509Certificate cert : trustStoreCertificates ) {
205+ FileUtils .writeStringToFile (trustStorePemFile , X509TestHelpers .pemEncodeX509Certificate (cert ), StandardCharsets .US_ASCII , true );
206+ }
196207 this .trustStorePemFile = trustStorePemFile ;
197208 }
198209 return trustStorePemFile ;
@@ -203,7 +214,7 @@ private File getTrustStorePkcs12File() throws IOException {
203214 File trustStorePkcs12File = File .createTempFile (TRUST_STORE_PREFIX , KeyStoreFileType .PKCS12 .getDefaultFileExtension (), tempDir );
204215 trustStorePkcs12File .deleteOnExit ();
205216 try (final FileOutputStream trustStoreOutputStream = new FileOutputStream (trustStorePkcs12File )) {
206- byte [] bytes = X509TestHelpers .certToPKCS12TrustStoreBytes (trustStoreCertificate , trustStorePassword );
217+ byte [] bytes = X509TestHelpers .certToPKCS12TrustStoreBytes (trustStoreCertificates . get ( 0 ) , trustStorePassword );
207218 trustStoreOutputStream .write (bytes );
208219 trustStoreOutputStream .flush ();
209220 } catch (GeneralSecurityException e ) {
@@ -220,7 +231,7 @@ private File getTrustStoreBcfksFile() throws IOException {
220231 TRUST_STORE_PREFIX , KeyStoreFileType .BCFKS .getDefaultFileExtension (), tempDir );
221232 trustStoreBcfksFile .deleteOnExit ();
222233 try (final FileOutputStream trustStoreOutputStream = new FileOutputStream (trustStoreBcfksFile )) {
223- byte [] bytes = X509TestHelpers .certToBCFKSTrustStoreBytes (trustStoreCertificate , trustStorePassword );
234+ byte [] bytes = X509TestHelpers .certToBCFKSTrustStoreBytes (trustStoreCertificates . get ( 0 ) , trustStorePassword );
224235 trustStoreOutputStream .write (bytes );
225236 trustStoreOutputStream .flush ();
226237 } catch (GeneralSecurityException e ) {
0 commit comments