I was trying to load the keystore from a p12 file , the behaviour is highly inconsistent where in the keystore.aliases().nextElement() gives proper alias once and displaying CN in other cases. In the later case I am not able to store the keystore (using keystore.store) and the output stream is empty .
Below is the code snippet. Let me know if I overlooked anything.
// the main code where i am facing issue
private byte[] generateKeyStoreData(String appName, Map<String, String> credentials)
throws ApplicationException {
try {
if (!credentials.containsKey(KEYSTORE)) {
throw new NullPointerException("No keystore provided");
}
if (!credentials.containsKey(KEYSTORE_PASSWORD)) {
throw new NullPointerException("No keystore password provided");
}
String keystoreStr = credentials.get(KEYSTORE);
char[] keystorePass = credentials.get(KEYSTORE_PASSWORD).toCharArray();
// I have printed the base64 string here and tried loading inside a standalone code
and it is working. The method is below
InputStream keystoreIs = base64stringToInputStream(keystoreStr);
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(keystoreIs, keystorePass);
// I printed the keyStore.aliases().nextElement() which returns correct alias "omss"
// but returns CN in cases where it fails.
ByteArrayOutputStream keyStoreOut = new ByteArrayOutputStream();
keyStore.store(keyStoreOut, keystorePass);
// I printed the keystoreOut.toByteArray() and it is empty in failing cases
return keyStoreOut.toByteArray();
} catch (Exception e) {
// exception
}
}
// the conversion code from base64string to bytearrayinputstream
private InputStream base64stringToInputStream(String str) {
byte[] ba = DatatypeConverter.parseBase64Binary(str);
return new ByteArrayInputStream(ba);
}
//--------------------------------------------------------------------
// Below is api which calls the generateKeystore
//-------------------------------------------------------------------
// We get the inputstream from the uploaded p12 file and the below api is called
public void createKeystore(InputStream certFile,
char[] password) {
Util.nullCheck(certFile,
"Certificate File cannot be null or empty");
Util.nullCheck(password, "Password Cannot be null");
try {
// the method is below
byte[] raw = toByteArray(certFile);
// converting to base64 string
String base64encodedString = DatatypeConverter
.printBase64Binary(raw);
//....... we create a map of keystore string and password
// and the call is made to generateKeystore method above
}
catch(Exception e){
}
// the inputstream is converted to bytearray inputstream
private static byte[] toByteArray(InputStream is) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int reads = is.read();
while (reads != -1) {
baos.write(reads);
reads = is.read();
}
return baos.toByteArray();
}
Looks like the keystore.load() is not using "SunJSSE" as the default keystore provider in my j2ee environment rather it was using oraclepki provider. Now that i am loading keystore.load(Is,"SunJSSE") it is able to load properly.