Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6531435

Inserting publicKey into JavaKeyStore and loading existing keys Failure

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not an Issue
    • Icon: P4 P4
    • None
    • 6
    • security-libs

      FULL PRODUCT VERSION :
      java version "1.6.0"
      Java(TM) SE Runtime Environment (build 1.6.0-b105)
      Java HotSpot(TM) Server VM (build 1.6.0-b105, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Linux host.domain 2.4.21-4.ELsmp #1 SMP Fri Oct 3 17:52:56 EDT 2003 i686 i686 i386 GNU/Linux

      A DESCRIPTION OF THE PROBLEM :
      Inserting a public key and a certicate chain failed.

      This feature, which was wrintten for JDK1.4.2 and (source code mentioned below)is functioning perfect. When I decided to port to JDK1.6, it started throwing mentioned exception. (in the error message)

      I downloaded the source code(JDK1.6) from your site, while verifying I found interesting as mentioned below.
      -- java.security.Keystore.class
          public final void setKeyEntry(String alias, Key key, char[] password,
                                        Certificate[] chain)
              throws KeyStoreException
          {
              if (!initialized) {
                  throw new KeyStoreException("Uninitialized keystore");
              }
              if ((key instanceof PrivateKey) &&
                  (chain == null || chain.length == 0)) {
                  throw new IllegalArgumentException("Private key must be "
                                                     + "accompanied by certificate "
                                                     + "chain");
              }
              keyStoreSpi.engineSetKeyEntry(alias, key, password, chain);
          }

      It validates whether the key is privateKey and accompanied by certicate chain. Does that mean publicKey with certificate of chain permitted ? In my case it's valid as I am sending the Public key accompanied by certificate chain. As you see the keyStoreSpi which is an Interface to JavaKeyStore (below mentioned Class), engineSetKeyEntry mandate for the privateKey.

      -- sun/security/provider/JavaKeyStore.class
          public void engineSetKeyEntry(String alias, Key key, char[] password,
                                        Certificate[] chain)
              throws KeyStoreException
          {
              KeyProtector keyProtector = null;

              if (!(key instanceof java.security.PrivateKey)) {
                  throw new KeyStoreException("Cannot store non-PrivateKeys");
              }
       }


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Create a Ceriticate and a publickey
      2. insert into keystore file $HOME/config/system.keystore
      using the attached code. (Keystore type is "JKS")


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Succefull insertion of the keyentry into the system.keystore file
      ACTUAL -
      The exceptions which is mentioned in the error message

      ERROR MESSAGES/STACK TRACES THAT OCCUR :

      Exception in thread "main" java.security.KeyStoreException: Cannot store non-PrivateKeys
      at sun.security.provider.JavaKeyStore.engineSetKeyEntry(Unknown Source)
      at java.security.KeyStore.setKeyEntry(Unknown Source)
      at KeyStoreExample.encrypt(KeyStoreExample.java:89)
      at KeyStoreExample.main(KeyStoreExample.java:39)

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
                 java.security.KeyStore keyStore = java.security.KeyStore.getInstance("JKS");
                      try {
                              java.io.FileInputStream ksStream = new java.io.FileInputStream(keyStoreFile);
                              keyStore.load(ksStream, password);
                      }
                      catch (java.io.FileNotFoundException ex) {
                      }
                      keyStore.load(null, password);
                      java.security.cert.CertificateFactory certificateFactory = java.security.cert.CertificateFactory.getInstance("X.509");
                      java.security.cert.Certificate cert = certificateFactory.generateCertificate(bCertificate);
                      java.security.cert.Certificate[] certArr = new java.security.cert.Certificate[1];
                      certArr[0] = cert;
                      java.security.PublicKey pk = cert.getPublicKey();
                      keyStore.setKeyEntry(alias, pk, password, certArr);
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      In my application (beta phase) I ignore the validation process to get around.

            xuelei Xuelei Fan
            ndcosta Nelson Dcosta (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: