diff --git a/meerkat-common/src/main/java/meerkat/crypto/concrete/ECDSASignature.java b/meerkat-common/src/main/java/meerkat/crypto/concrete/ECDSASignature.java index 4fb8de5..360ea53 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/concrete/ECDSASignature.java +++ b/meerkat-common/src/main/java/meerkat/crypto/concrete/ECDSASignature.java @@ -230,7 +230,34 @@ public class ECDSASignature extends GlobalCryptoSetup implements DigitalSignatur try { Certificate cert = keyStore.getCertificate(alias); logger.trace("keystore entry {}, has cert type {}", alias, cert.getClass()); - Key key = keyStore.getKey(alias, null); + Key key; + try { + key = keyStore.getKey(alias, null); + } catch (UnrecoverableKeyException e) { + // This might be a keystore that doesn't support callback handlers + // (e.g., Java 8 PKCS12) + // Manually extract password using callback handler + char[] password = null; + KeyStore.ProtectionParameter prot = keyStoreBuilder.getProtectionParameter(alias); + + if (prot instanceof KeyStore.PasswordProtection) { + password = ((KeyStore.PasswordProtection) prot).getPassword(); + } else if (prot instanceof KeyStore.CallbackHandlerProtection) { + PasswordCallback callback = new PasswordCallback("Password for " + alias + "?", false); + Callback[] callbacks = { callback }; + try { + ((KeyStore.CallbackHandlerProtection) prot).getCallbackHandler().handle(callbacks); + password = callback.getPassword(); + } catch (UnsupportedCallbackException e1) { + logger.error("PasswordCallback fallback not supported!", e1); + throw new UnrecoverableKeyException("Couldn't use password callback to get key"); + } + } else { + logger.error("Unrecognized protection handler for keystore: {}", prot.getClass()); + throw new UnrecoverableKeyException("Unrecognized protection handler for keystore"); + } + key = keyStore.getKey(alias, password); + } logger.trace("keystore entry {}, has key type {}", alias, key.getClass()); if (key instanceof PrivateKey) { loadedSigningKeyId = computeCertificateFingerprint(cert);