title: Saving certificate chain in a pkcs12 keystore
body: <p>The following code: </p>
  
  <pre><code>//used Bouncy Castle provider for keyStore
  keyStore.setKeyEntry(alias, (Key)keyPair.getPrivate(), pwd, certChain);  
  </code></pre>
  
  <p>where certChain holds the end certificate and the issuer certificate (i.e. two certificates),<br>
  doesn't save the issuer certificate as part of the chain in the saved to the file system keystore file if the keyStore is an instance of <code>PKCS12</code>.  </p>
  
  <p>It does save both certificates if the keystore type is <code>PKCS12-3DES-3DES</code>.
  Why is this? Doesn't a PKCS12 suppose to have both certificates are part of the chain?</p>
  
  <p>EDIT: Here's an <a href="http://sscce.org/" rel="noreferrer">SSCCE</a>. This works fine with <code>"JKS"</code>, fails with <code>"PKCS12"</code>: Only the first certificate in the chain is accessible via <code>getCertificateChain(String)</code>. The saved file can be opened with <code>openssl pkcs12</code> revealing both certificates.</p>
  
  <pre><code>    public void testKeyStore() {
      try {
          KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
          keyPairGenerator.initialize(1024);
          KeyPair keyPair = keyPairGenerator.generateKeyPair();
          PublicKey publicKey = keyPair.getPublic();
          PrivateKey privateKey = keyPair.getPrivate();
          Certificate[] outChain = { createCertificate("CN=CA", publicKey, privateKey), createCertificate("CN=Client", publicKey, privateKey) };
  
          KeyStore outStore = KeyStore.getInstance("PKCS12");
          outStore.load(null, "secret".toCharArray());
          outStore.setKeyEntry("mykey", privateKey, "secret".toCharArray(), outChain);            
          OutputStream outputStream = new FileOutputStream("c:/outstore.pkcs12");
          outStore.store(outputStream, "secret".toCharArray());
          outputStream.flush();
          outputStream.close();
  
          KeyStore inStore = KeyStore.getInstance("PKCS12");      
          inStore.load(new FileInputStream("c:/outstore.pkcs12"), "secret".toCharArray());
          Key key = outStore.getKey("myKey", "secret".toCharArray());
          assertEquals(privateKey, key);
  
          Certificate[] inChain = outStore.getCertificateChain("mykey");
          assertNotNull(inChain);
          assertEquals(outChain.length, inChain.length);
      } catch (Exception e) {
          e.printStackTrace();
          fail(e.getMessage());
      }
  }
  
  private static X509Certificate createCertificate(String dn, PublicKey publicKey, PrivateKey privateKey) throws Exception {
      X509V3CertificateGenerator certGenerator = new X509V3CertificateGenerator();
      certGenerator.setSerialNumber(new BigInteger("1"));
      certGenerator.setIssuerDN(new X509Name(dn));
      certGenerator.setSubjectDN(new X509Name(dn));
      certGenerator.setNotBefore(Calendar.getInstance().getTime());
      certGenerator.setNotAfter(Calendar.getInstance().getTime());
      certGenerator.setPublicKey(publicKey);
      certGenerator.setSignatureAlgorithm("SHA1withRSA");
      X509Certificate certificate = (X509Certificate)certGenerator.generate(privateKey, "BC");
      return certificate;
  }
  </code></pre>