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

Empty string alias in KeyStore throws StringIndexOutOfBoundsException for getEntry()

    Details

    • Subcomponent:
    • Resolved In Build:
      b22
    • CPU:
      generic
    • OS:
      generic
    • Verification:
      Verified

      Backports

        Description

        FULL PRODUCT VERSION :
        java version "1.8.0_112"
        Java(TM) SE Runtime Environment (build 1.8.0_112-b15)
        Java HotSpot(TM) 64-Bit Server VM (build 25.112-b15, mixed mode)

        ADDITIONAL OS VERSION INFORMATION :
        Microsoft Windows [Version 10.0.14393]
        Linux comet.digitalgraffiti.org 4.8.16-300.fc25.x86_64 #1 SMP

        A DESCRIPTION OF THE PROBLEM :
        java.security.KeyStore allows the creation of a KeyStore.Entry with an empty string alias (""). When iterating over the aliases enumeration calling KeyStore.getEntry for the empty string alias throws:

        java.lang.StringIndexOutOfBoundsException: String index out of range: 0
        at java.lang.String.charAt(String.java:658)
        at java.security.PKCS12Attribute.<init>(PKCS12Attribute.java:88)
        at sun.security.pkcs12.PKCS12KeyStore.getAttributes(PKCS12KeyStore.java:1391)
        at sun.security.pkcs12.PKCS12KeyStore.engineGetEntry(PKCS12KeyStore.java:1287)
        at java.security.KeyStore.getEntry(KeyStore.java:1521)
         

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
                    KeyStore keyStore = KeyStore.getInstance("PKCS12");
                    keyStore.load(null,null);
                    keyStore.setKeyEntry("", keyPair.getPrivate(), password, new X509Certificate[]{certificate});

                    Enumeration<String> aliases = keyStore.aliases();
                    while(aliases.hasMoreElements()){
                        String alias = aliases.nextElement();
                        keyStore.getEntry(alias, passwordProtection);
                    }


        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        Expected the "" alias to return the KeyStore.Entry

        Note: Keystore.getKey("", password), keyStore.deleteEntry("")
         and KeyStore.getCertificateChain("") work as expected with an empty string alias.
        ACTUAL -
        KeyStore.getEntry("", passwordProtection) throws
        StringIndexOutOfBoundsException

        ERROR MESSAGES/STACK TRACES THAT OCCUR :
         java.lang.StringIndexOutOfBoundsException: String index out of range: 0
        at java.lang.String.charAt(String.java:658)
        at java.security.PKCS12Attribute.<init>(PKCS12Attribute.java:88)
        at sun.security.pkcs12.PKCS12KeyStore.getAttributes(PKCS12KeyStore.java:1391)
        at sun.security.pkcs12.PKCS12KeyStore.engineGetEntry(PKCS12KeyStore.java:1287)
        at java.security.KeyStore.getEntry(KeyStore.java:1521)

        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
                    KeyStore keyStore = KeyStore.getInstance("PKCS12");
                    keyStore.load(null,null);
                    keyStore.setKeyEntry("", keyPair.getPrivate(), password, new X509Certificate[]{certificate});

                    Enumeration<String> aliases = keyStore.aliases();
                    while(aliases.hasMoreElements()){
                        String alias = aliases.nextElement();
                        keyStore.getEntry(alias, passwordProtection); // StringIndexOutOfBoundsException here
                    }

        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        You can test for the "" alias using KeyStore.getCertificateChain(""). If it is not null you can retrieve the key and/or certificate and create a new KeyStore.Entry that has an alias of a non-empty string and then delete the "" alias.

        if (keyStore.getCertificateChain("") !=null) fixAlias(keyStore, password);

            public static KeyStore fixAlias(KeyStore keyStore, char[] password) throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException {
                Key k = keyStore.getKey("", password);
                Certificate[] certs = keyStore.getCertificateChain("");

                keyStore.deleteEntry("");

                keyStore.setKeyEntry("newAlias", k, password, certs);

                return keyStore;
            }

          Attachments

            Issue Links

              Activity

                People

                • Assignee:
                  vinnie Vincent Ryan
                  Reporter:
                  webbuggrp Webbug Group
                • Votes:
                  0 Vote for this issue
                  Watchers:
                  6 Start watching this issue

                  Dates

                  • Created:
                    Updated:
                    Resolved: