I need to establish a secure socket connection on Java/Kotlin.
The server gave me 2 files:
- The CA certificate.
- The server key in the "pem" format.
I converted both keys to the JKS format using the portecle.
For some reason the java.lang.NullPointerException
occurs during the handshake. OpenJDK crashes here. Here is my source code:
class Connection(
val host: String,
val port: Int
)
class KeyStoreParams(
val inputStream: InputStream,
val password: String
)
class SocketClient(
private val connection: Connection,
private val keyStoreParams: KeyStoreParams,
private val trustStoreParams: KeyStoreParams
) {
companion object {
private val sslContextType = "TLS"
private var keyStoreType = "JKS"
}
fun connect() {
val sslContext = SSLContext.getInstance(sslContextType)
sslContext.init(getKeyManagers(), getTrustManagers(), SecureRandom())
val socket = sslContext.socketFactory.createSocket(connection.host, connection.port) as SSLSocket
socket.startHandshake()
}
private fun getKeyManagers(): Array<KeyManager> {
val keyStore = getKeyStore(keyStoreParams.inputStream, keyStoreParams.password)
val keyManagerAlgorithm = KeyManagerFactory.getDefaultAlgorithm()
val keyManagerFactory = KeyManagerFactory.getInstance(keyManagerAlgorithm)
keyManagerFactory.init(keyStore, keyStoreParams.password.toCharArray())
return keyManagerFactory.keyManagers
}
private fun getTrustManagers(): Array<TrustManager> {
val keyStore = getKeyStore(trustStoreParams.inputStream, trustStoreParams.password)
val trustManagerAlgorithm = TrustManagerFactory.getDefaultAlgorithm()
val trustManagerFactory = TrustManagerFactory.getInstance(trustManagerAlgorithm)
trustManagerFactory.init(keyStore)
return trustManagerFactory.trustManagers
}
private fun getKeyStore(inputStream: InputStream, password: String): KeyStore {
val keyStore = KeyStore.getInstance(keyStoreType)
keyStore.load(inputStream, password.toCharArray())
inputStream.close()
return keyStore
}
}
fun connect() {
val connection = Connection(host, port)
val keyStoreParams = KeyStoreParams(streamForFile(keyStorePath), keyStorePassword)
val trustStoreParams = KeyStoreParams(streamForFile(trustStorePath), trustStorePassword)
val client = SocketClient(connection, keyStoreParams, trustStoreParams)
client.connect()
}
private fun streamForFile(path: String): InputStream {
return javaClass.classLoader.getResource(path)!!.openStream()
}
Here is the stacktrace:
Exception in thread "main" javax.net.ssl.SSLException
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:133)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:325)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:268)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:263)
at java.base/sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1667)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:454)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:412)
at com.example.test.network.socket.SocketClient.connect(SocketClient.kt:23)
at com.example.test.network.NetworkManager.connect(NetworkManager.kt:24)
at MainKt.main(main.kt:5)
at MainKt.main(main.kt)
Caused by: java.lang.NullPointerException
at java.base/sun.security.ssl.CertificateRequest$ClientCertificateType.getKeyTypes(CertificateRequest.java:136)
at java.base/sun.security.ssl.CertificateRequest$T10CertificateRequestMessage.getKeyTypes(CertificateRequest.java:199)
at java.base/sun.security.ssl.CertificateRequest$T10CertificateRequestConsumer.consume(CertificateRequest.java:365)
at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:396)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:445)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:423)
at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:182)
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:171)
at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1475)
at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1381)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:441)
... 5 more
Thanks!