Skip to content
Snippets Groups Projects
Commit 1ecc791a authored by davidepianca98's avatar davidepianca98
Browse files

Add EC private key support on JVM

parent 535e86b9
No related branches found
No related tags found
No related merge requests found
...@@ -13,7 +13,6 @@ buildscript { ...@@ -13,7 +13,6 @@ buildscript {
plugins { plugins {
alias(libs.plugins.kotlin.multiplatform) apply false alias(libs.plugins.kotlin.multiplatform) apply false
alias(libs.plugins.complete.kotlin)
alias(libs.plugins.goncalossilva.resources) alias(libs.plugins.goncalossilva.resources)
} }
......
...@@ -3,7 +3,6 @@ serialization = "1.7.3" ...@@ -3,7 +3,6 @@ serialization = "1.7.3"
coroutines = "1.9.0" coroutines = "1.9.0"
atomicfu = "0.26.1" atomicfu = "0.26.1"
nodeWrapper = "20.11.30-pre.732" nodeWrapper = "20.11.30-pre.732"
completeKotlin = "1.1.0"
silvaResources = "0.4.0" silvaResources = "0.4.0"
kotlin = "2.1.0" kotlin = "2.1.0"
shadow = "8.3.5" shadow = "8.3.5"
...@@ -20,6 +19,5 @@ goncalossilva-resources = { module = "com.goncalossilva:resources", version.ref ...@@ -20,6 +19,5 @@ goncalossilva-resources = { module = "com.goncalossilva:resources", version.ref
[plugins] [plugins]
kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
complete-kotlin = { id = "com.louiscad.complete-kotlin", version.ref = "completeKotlin" }
goncalossilva-resources = { id = "com.goncalossilva.resources", version.ref = "silvaResources" } goncalossilva-resources = { id = "com.goncalossilva.resources", version.ref = "silvaResources" }
johnrengelman-shadow = { id = "com.gradleup.shadow", version.ref = "shadow" } johnrengelman-shadow = { id = "com.gradleup.shadow", version.ref = "shadow" }
...@@ -96,7 +96,6 @@ import kotlinx.coroutines.yield ...@@ -96,7 +96,6 @@ import kotlinx.coroutines.yield
* @param publishReceived called when a PUBLISH packet has been received * @param publishReceived called when a PUBLISH packet has been received
*/ */
public class MQTTClient( public class MQTTClient(
private val autoInit: Boolean = true,
private val mqttVersion: MQTTVersion, private val mqttVersion: MQTTVersion,
private val address: String, private val address: String,
private val port: Int, private val port: Int,
...@@ -115,6 +114,7 @@ public class MQTTClient( ...@@ -115,6 +114,7 @@ public class MQTTClient(
private val willQos: Qos = Qos.AT_MOST_ONCE, private val willQos: Qos = Qos.AT_MOST_ONCE,
private val connackTimeout: Int = 30, private val connackTimeout: Int = 30,
private val connectTimeout: Int = 30, private val connectTimeout: Int = 30,
private val autoInit: Boolean = true,
private val enhancedAuthCallback: (authenticationData: UByteArray?) -> UByteArray? = { null }, private val enhancedAuthCallback: (authenticationData: UByteArray?) -> UByteArray? = { null },
private val onConnected: (connack: MQTTConnack) -> Unit = {}, private val onConnected: (connack: MQTTConnack) -> Unit = {},
private val onDisconnected: (disconnect: MQTTDisconnect?) -> Unit = {}, private val onDisconnected: (disconnect: MQTTDisconnect?) -> Unit = {},
......
...@@ -12,7 +12,9 @@ import java.security.KeyFactory ...@@ -12,7 +12,9 @@ import java.security.KeyFactory
import java.security.KeyStore import java.security.KeyStore
import java.security.cert.CertificateFactory import java.security.cert.CertificateFactory
import java.security.cert.X509Certificate import java.security.cert.X509Certificate
import java.security.interfaces.ECPrivateKey
import java.security.interfaces.RSAPrivateKey import java.security.interfaces.RSAPrivateKey
import java.security.spec.InvalidKeySpecException
import java.security.spec.PKCS8EncodedKeySpec import java.security.spec.PKCS8EncodedKeySpec
import java.util.* import java.util.*
import javax.net.ssl.KeyManagerFactory import javax.net.ssl.KeyManagerFactory
...@@ -77,7 +79,12 @@ public actual class TLSClientSocket actual constructor( ...@@ -77,7 +79,12 @@ public actual class TLSClientSocket actual constructor(
val keyStore = KeyStore.getInstance(KeyStore.getDefaultType()) val keyStore = KeyStore.getInstance(KeyStore.getDefaultType())
keyStore.load(null, null) keyStore.load(null, null)
val key = getPrivateKeyFromString(if (tlsSettings.clientCertificateKey!!.isValidPem()) tlsSettings.clientCertificateKey!! else FileInputStream(tlsSettings.clientCertificateKey!!).bufferedReader().readText()) val keyContent = if (tlsSettings.clientCertificateKey!!.isValidPem()) tlsSettings.clientCertificateKey!! else FileInputStream(tlsSettings.clientCertificateKey!!).bufferedReader().readText();
val key = try {
getRSAPrivateKeyFromString(keyContent)
} catch (e: InvalidKeySpecException) {
getECPrivateKeyFromString(keyContent)
}
keyStore.setKeyEntry("client", key, tlsSettings.clientCertificatePassword?.toCharArray(), arrayOf(certificate)) keyStore.setKeyEntry("client", key, tlsSettings.clientCertificatePassword?.toCharArray(), arrayOf(certificate))
val kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()) val kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
...@@ -101,7 +108,7 @@ public actual class TLSClientSocket actual constructor( ...@@ -101,7 +108,7 @@ public actual class TLSClientSocket actual constructor(
} }
public companion object { public companion object {
private fun getPrivateKeyFromString(key: String): RSAPrivateKey { private fun getRSAPrivateKeyFromString(key: String): RSAPrivateKey {
val privateKeyPEM = key val privateKeyPEM = key
.replace("-----BEGIN PRIVATE KEY-----", "") .replace("-----BEGIN PRIVATE KEY-----", "")
.replace("-----END PRIVATE KEY-----", "") .replace("-----END PRIVATE KEY-----", "")
...@@ -111,6 +118,17 @@ public actual class TLSClientSocket actual constructor( ...@@ -111,6 +118,17 @@ public actual class TLSClientSocket actual constructor(
val keySpec = PKCS8EncodedKeySpec(encoded) val keySpec = PKCS8EncodedKeySpec(encoded)
return kf.generatePrivate(keySpec) as RSAPrivateKey return kf.generatePrivate(keySpec) as RSAPrivateKey
} }
private fun getECPrivateKeyFromString(key: String): ECPrivateKey {
val privateKeyPEM = key
.replace("-----BEGIN EC PRIVATE KEY-----", "")
.replace("-----END EC PRIVATE KEY-----", "")
.replace("\n","")
val encoded = Base64.getDecoder().decode(privateKeyPEM)
val kf = KeyFactory.getInstance("EC")
val keySpec = PKCS8EncodedKeySpec(encoded)
return kf.generatePrivate(keySpec) as ECPrivateKey
}
} }
override fun send(data: UByteArray) { override fun send(data: UByteArray) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment