0

I have a service that provides a key and private RSA certificate that I need to turn into an SSLSocketFactory. I am able to initialize everything, but when calling getKeyManagers on the KeyManagerFactory, a RuntimeException saying "java.lang.RuntimeException: forget something!" is thrown. What am I missing?

return try {
    val sslContext = SSLContext.getDefault()
    val keyManager = KeyManagerFactory.getInstance("PKIX")
    val keyStore = KeyStore.getInstance(KeyStore.getDefaultType())
    val certificateFactory = CertificateFactory.getInstance("X.509")
    keyStore.load(null)
    keyStore.setKeyEntry(
        "agragps",
        privateCertificate.toByteArray(),
        arrayOf(certificateFactory.generateCertificate(publicCertificate.byteInputStream())))
    keyManager.init(keyStore, charArrayOf())
    val managers = keyManager.keyManagers
    sslContext.init(managers, null, null)
    sslContext.socketFactory
} catch (e: Exception) {
    null
}

Here is the full exception:

java.lang.RuntimeException: forget something!
    at com.android.org.bouncycastle.jcajce.provider.keystore.bc.BcKeyStoreSpi$StoreEntry.getObject(BcKeyStoreSpi.java:329)
    at com.android.org.bouncycastle.jcajce.provider.keystore.bc.BcKeyStoreSpi.engineGetKey(BcKeyStoreSpi.java:619)
    at java.security.KeyStoreSpi.engineGetEntry(KeyStoreSpi.java:511)
    at java.security.KeyStore.getEntry(KeyStore.java:1581)
    at com.android.org.conscrypt.KeyManagerImpl.<init>(KeyManagerImpl.java:74)
    at com.android.org.conscrypt.KeyManagerFactoryImpl.engineGetKeyManagers(KeyManagerFactoryImpl.java:120)
    at javax.net.ssl.KeyManagerFactory.getKeyManagers(KeyManagerFactory.java:305)
    at com.agragps.agragps.?.?Kt.loadCertificates(ThingStreamClientAndroid.kt:64)
    at com.agragps.agragps.?.?Kt.loadCertificates(ThingStreamClientAndroid.kt:38)
    at com.agragps.agragps.services.?.?$connectPointPerfect$2.invokeSuspend(MQTTService.kt:113)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
    at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:115)
    at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:100)
    at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:793)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:697)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:684)

Converting the public PEM to DER gives the same result:

val publicDER = Base64.decode(publicCertificate
    .replace("-----BEGIN CERTIFICATE-----\n", "")
    .replace("\n-----END CERTIFICATE-----\n", "")
    .encodeToByteArray(), Base64.DEFAULT)
keyStore.setKeyEntry(
    "agragps",
    privateCertificate.toByteArray(),
    arrayOf(certificateFactory.generateCertificate(publicDER.inputStream())))

privateCertificate is a String starting with "-----BEGIN RSA PRIVATE KEY-----" and ending in "-----END RSA PRIVATE KEY-----". publicCertificate is a String starting with "-----BEGIN CERTIFICATE-----" and ending in "-----END CERTIFICATE-----".

I'm not very experienced with working with certificates. Any help is really appreciated.

cj-
  • 167
  • 1
  • 12
  • 1
    *a RuntimeException saying "java.lang.RuntimeException: forget something!" is thrown.* Please post that *verbatim, formatted as code* – g00se Jul 04 '23 at 18:59
  • Absolutely, it has been included – cj- Jul 04 '23 at 19:49
  • Java keystores don't support PEM certificates. I don't know if that bouncycastle stuff is supposed to help. – Arfur Narf Jul 05 '23 at 03:12
  • Attempted to convert the PEM certificate to DER (noted here https://stackoverflow.com/a/54670753/10152911), gave the same result. – cj- Jul 05 '23 at 17:06

0 Answers0