diff --git a/kmqtt-client/src/iosArm64Main/kotlin/TLSClientEngine.kt b/kmqtt-client/src/iosArm64Main/kotlin/TLSClientEngine.kt index d5e331b30bb2dd0e5150a51348b43be5a8f3b858..b180dea3fb966b42a150ca3e66decb194b6cd0f3 100644 --- a/kmqtt-client/src/iosArm64Main/kotlin/TLSClientEngine.kt +++ b/kmqtt-client/src/iosArm64Main/kotlin/TLSClientEngine.kt @@ -69,8 +69,18 @@ internal actual class TLSClientEngine actual constructor(tlsSettings: TLSClientS } } } else { - if (SSL_CTX_load_verify_locations(sslContext, null, getenv(X509_get_default_cert_dir_env()?.toKString())?.toKString()) != 1) { - throw Exception("Server certificate path not found") + if (!tlsSettings.checkServerCertificate) { + SSL_CTX_set_cert_verify_callback( + sslContext, + staticCFunction { buf: CPointer<X509_STORE_CTX>?, arg: COpaquePointer? -> + 1 + }, + null + ) + } else { + if (SSL_CTX_load_verify_locations(sslContext, null, getenv(X509_get_default_cert_dir_env()?.toKString())?.toKString()) != 1) { + throw Exception("Server certificate path not found") + } } } diff --git a/kmqtt-client/src/iosSimulatorArm64Main/kotlin/TLSClientEngine.kt b/kmqtt-client/src/iosSimulatorArm64Main/kotlin/TLSClientEngine.kt index d5e331b30bb2dd0e5150a51348b43be5a8f3b858..b180dea3fb966b42a150ca3e66decb194b6cd0f3 100644 --- a/kmqtt-client/src/iosSimulatorArm64Main/kotlin/TLSClientEngine.kt +++ b/kmqtt-client/src/iosSimulatorArm64Main/kotlin/TLSClientEngine.kt @@ -69,8 +69,18 @@ internal actual class TLSClientEngine actual constructor(tlsSettings: TLSClientS } } } else { - if (SSL_CTX_load_verify_locations(sslContext, null, getenv(X509_get_default_cert_dir_env()?.toKString())?.toKString()) != 1) { - throw Exception("Server certificate path not found") + if (!tlsSettings.checkServerCertificate) { + SSL_CTX_set_cert_verify_callback( + sslContext, + staticCFunction { buf: CPointer<X509_STORE_CTX>?, arg: COpaquePointer? -> + 1 + }, + null + ) + } else { + if (SSL_CTX_load_verify_locations(sslContext, null, getenv(X509_get_default_cert_dir_env()?.toKString())?.toKString()) != 1) { + throw Exception("Server certificate path not found") + } } } diff --git a/kmqtt-client/src/iosX64Main/kotlin/TLSClientEngine.kt b/kmqtt-client/src/iosX64Main/kotlin/TLSClientEngine.kt index d5e331b30bb2dd0e5150a51348b43be5a8f3b858..b180dea3fb966b42a150ca3e66decb194b6cd0f3 100644 --- a/kmqtt-client/src/iosX64Main/kotlin/TLSClientEngine.kt +++ b/kmqtt-client/src/iosX64Main/kotlin/TLSClientEngine.kt @@ -69,8 +69,18 @@ internal actual class TLSClientEngine actual constructor(tlsSettings: TLSClientS } } } else { - if (SSL_CTX_load_verify_locations(sslContext, null, getenv(X509_get_default_cert_dir_env()?.toKString())?.toKString()) != 1) { - throw Exception("Server certificate path not found") + if (!tlsSettings.checkServerCertificate) { + SSL_CTX_set_cert_verify_callback( + sslContext, + staticCFunction { buf: CPointer<X509_STORE_CTX>?, arg: COpaquePointer? -> + 1 + }, + null + ) + } else { + if (SSL_CTX_load_verify_locations(sslContext, null, getenv(X509_get_default_cert_dir_env()?.toKString())?.toKString()) != 1) { + throw Exception("Server certificate path not found") + } } } diff --git a/kmqtt-client/src/jvmMain/kotlin/TLSClientSocket.kt b/kmqtt-client/src/jvmMain/kotlin/TLSClientSocket.kt index 923cc63979be1cab0613737a0f9bb264067cf7fd..b6af8271da4bf1bab131f83087e036bbf259f887 100644 --- a/kmqtt-client/src/jvmMain/kotlin/TLSClientSocket.kt +++ b/kmqtt-client/src/jvmMain/kotlin/TLSClientSocket.kt @@ -9,6 +9,7 @@ import java.nio.channels.SocketChannel import java.security.KeyFactory import java.security.KeyStore import java.security.cert.CertificateFactory +import java.security.cert.X509Certificate import java.security.interfaces.RSAPrivateKey import java.security.spec.PKCS8EncodedKeySpec import java.util.* @@ -16,6 +17,7 @@ import javax.net.ssl.KeyManagerFactory import javax.net.ssl.SSLContext import javax.net.ssl.SSLEngineResult import javax.net.ssl.TrustManagerFactory +import javax.net.ssl.X509TrustManager public actual class TLSClientSocket actual constructor( @@ -49,7 +51,19 @@ public actual class TLSClientSocket actual constructor( trustManagerFactory.trustManagers } else { - null + if (!tlsSettings.checkServerCertificate) { + arrayOf(object : X509TrustManager { + override fun checkClientTrusted(chain: Array<out X509Certificate>?, authType: String?) {} + + override fun checkServerTrusted(chain: Array<out X509Certificate>?, authType: String?) {} + + override fun getAcceptedIssuers(): Array<X509Certificate> { + return arrayOf() + } + }) + } else { + null + } } val keyManagers = if (tlsSettings.clientCertificate != null) { diff --git a/kmqtt-client/src/linuxArm64Main/kotlin/TLSClientEngine.kt b/kmqtt-client/src/linuxArm64Main/kotlin/TLSClientEngine.kt index d5e331b30bb2dd0e5150a51348b43be5a8f3b858..b180dea3fb966b42a150ca3e66decb194b6cd0f3 100644 --- a/kmqtt-client/src/linuxArm64Main/kotlin/TLSClientEngine.kt +++ b/kmqtt-client/src/linuxArm64Main/kotlin/TLSClientEngine.kt @@ -69,8 +69,18 @@ internal actual class TLSClientEngine actual constructor(tlsSettings: TLSClientS } } } else { - if (SSL_CTX_load_verify_locations(sslContext, null, getenv(X509_get_default_cert_dir_env()?.toKString())?.toKString()) != 1) { - throw Exception("Server certificate path not found") + if (!tlsSettings.checkServerCertificate) { + SSL_CTX_set_cert_verify_callback( + sslContext, + staticCFunction { buf: CPointer<X509_STORE_CTX>?, arg: COpaquePointer? -> + 1 + }, + null + ) + } else { + if (SSL_CTX_load_verify_locations(sslContext, null, getenv(X509_get_default_cert_dir_env()?.toKString())?.toKString()) != 1) { + throw Exception("Server certificate path not found") + } } } diff --git a/kmqtt-client/src/linuxX64Main/kotlin/TLSClientEngine.kt b/kmqtt-client/src/linuxX64Main/kotlin/TLSClientEngine.kt index d5e331b30bb2dd0e5150a51348b43be5a8f3b858..b180dea3fb966b42a150ca3e66decb194b6cd0f3 100644 --- a/kmqtt-client/src/linuxX64Main/kotlin/TLSClientEngine.kt +++ b/kmqtt-client/src/linuxX64Main/kotlin/TLSClientEngine.kt @@ -69,8 +69,18 @@ internal actual class TLSClientEngine actual constructor(tlsSettings: TLSClientS } } } else { - if (SSL_CTX_load_verify_locations(sslContext, null, getenv(X509_get_default_cert_dir_env()?.toKString())?.toKString()) != 1) { - throw Exception("Server certificate path not found") + if (!tlsSettings.checkServerCertificate) { + SSL_CTX_set_cert_verify_callback( + sslContext, + staticCFunction { buf: CPointer<X509_STORE_CTX>?, arg: COpaquePointer? -> + 1 + }, + null + ) + } else { + if (SSL_CTX_load_verify_locations(sslContext, null, getenv(X509_get_default_cert_dir_env()?.toKString())?.toKString()) != 1) { + throw Exception("Server certificate path not found") + } } } diff --git a/kmqtt-client/src/macosArm64Main/kotlin/TLSClientEngine.kt b/kmqtt-client/src/macosArm64Main/kotlin/TLSClientEngine.kt index d5e331b30bb2dd0e5150a51348b43be5a8f3b858..b180dea3fb966b42a150ca3e66decb194b6cd0f3 100644 --- a/kmqtt-client/src/macosArm64Main/kotlin/TLSClientEngine.kt +++ b/kmqtt-client/src/macosArm64Main/kotlin/TLSClientEngine.kt @@ -69,8 +69,18 @@ internal actual class TLSClientEngine actual constructor(tlsSettings: TLSClientS } } } else { - if (SSL_CTX_load_verify_locations(sslContext, null, getenv(X509_get_default_cert_dir_env()?.toKString())?.toKString()) != 1) { - throw Exception("Server certificate path not found") + if (!tlsSettings.checkServerCertificate) { + SSL_CTX_set_cert_verify_callback( + sslContext, + staticCFunction { buf: CPointer<X509_STORE_CTX>?, arg: COpaquePointer? -> + 1 + }, + null + ) + } else { + if (SSL_CTX_load_verify_locations(sslContext, null, getenv(X509_get_default_cert_dir_env()?.toKString())?.toKString()) != 1) { + throw Exception("Server certificate path not found") + } } } diff --git a/kmqtt-client/src/macosX64Main/kotlin/TLSClientEngine.kt b/kmqtt-client/src/macosX64Main/kotlin/TLSClientEngine.kt index d5e331b30bb2dd0e5150a51348b43be5a8f3b858..b180dea3fb966b42a150ca3e66decb194b6cd0f3 100644 --- a/kmqtt-client/src/macosX64Main/kotlin/TLSClientEngine.kt +++ b/kmqtt-client/src/macosX64Main/kotlin/TLSClientEngine.kt @@ -69,8 +69,18 @@ internal actual class TLSClientEngine actual constructor(tlsSettings: TLSClientS } } } else { - if (SSL_CTX_load_verify_locations(sslContext, null, getenv(X509_get_default_cert_dir_env()?.toKString())?.toKString()) != 1) { - throw Exception("Server certificate path not found") + if (!tlsSettings.checkServerCertificate) { + SSL_CTX_set_cert_verify_callback( + sslContext, + staticCFunction { buf: CPointer<X509_STORE_CTX>?, arg: COpaquePointer? -> + 1 + }, + null + ) + } else { + if (SSL_CTX_load_verify_locations(sslContext, null, getenv(X509_get_default_cert_dir_env()?.toKString())?.toKString()) != 1) { + throw Exception("Server certificate path not found") + } } } diff --git a/kmqtt-client/src/mingwX64Main/kotlin/TLSClientEngine.kt b/kmqtt-client/src/mingwX64Main/kotlin/TLSClientEngine.kt index d5e331b30bb2dd0e5150a51348b43be5a8f3b858..b180dea3fb966b42a150ca3e66decb194b6cd0f3 100644 --- a/kmqtt-client/src/mingwX64Main/kotlin/TLSClientEngine.kt +++ b/kmqtt-client/src/mingwX64Main/kotlin/TLSClientEngine.kt @@ -69,8 +69,18 @@ internal actual class TLSClientEngine actual constructor(tlsSettings: TLSClientS } } } else { - if (SSL_CTX_load_verify_locations(sslContext, null, getenv(X509_get_default_cert_dir_env()?.toKString())?.toKString()) != 1) { - throw Exception("Server certificate path not found") + if (!tlsSettings.checkServerCertificate) { + SSL_CTX_set_cert_verify_callback( + sslContext, + staticCFunction { buf: CPointer<X509_STORE_CTX>?, arg: COpaquePointer? -> + 1 + }, + null + ) + } else { + if (SSL_CTX_load_verify_locations(sslContext, null, getenv(X509_get_default_cert_dir_env()?.toKString())?.toKString()) != 1) { + throw Exception("Server certificate path not found") + } } } diff --git a/kmqtt-client/src/tvosArm64Main/kotlin/TLSClientEngine.kt b/kmqtt-client/src/tvosArm64Main/kotlin/TLSClientEngine.kt index d5e331b30bb2dd0e5150a51348b43be5a8f3b858..b180dea3fb966b42a150ca3e66decb194b6cd0f3 100644 --- a/kmqtt-client/src/tvosArm64Main/kotlin/TLSClientEngine.kt +++ b/kmqtt-client/src/tvosArm64Main/kotlin/TLSClientEngine.kt @@ -69,8 +69,18 @@ internal actual class TLSClientEngine actual constructor(tlsSettings: TLSClientS } } } else { - if (SSL_CTX_load_verify_locations(sslContext, null, getenv(X509_get_default_cert_dir_env()?.toKString())?.toKString()) != 1) { - throw Exception("Server certificate path not found") + if (!tlsSettings.checkServerCertificate) { + SSL_CTX_set_cert_verify_callback( + sslContext, + staticCFunction { buf: CPointer<X509_STORE_CTX>?, arg: COpaquePointer? -> + 1 + }, + null + ) + } else { + if (SSL_CTX_load_verify_locations(sslContext, null, getenv(X509_get_default_cert_dir_env()?.toKString())?.toKString()) != 1) { + throw Exception("Server certificate path not found") + } } } diff --git a/kmqtt-client/src/tvosSimulatorArm64Main/kotlin/TLSClientEngine.kt b/kmqtt-client/src/tvosSimulatorArm64Main/kotlin/TLSClientEngine.kt index d5e331b30bb2dd0e5150a51348b43be5a8f3b858..b180dea3fb966b42a150ca3e66decb194b6cd0f3 100644 --- a/kmqtt-client/src/tvosSimulatorArm64Main/kotlin/TLSClientEngine.kt +++ b/kmqtt-client/src/tvosSimulatorArm64Main/kotlin/TLSClientEngine.kt @@ -69,8 +69,18 @@ internal actual class TLSClientEngine actual constructor(tlsSettings: TLSClientS } } } else { - if (SSL_CTX_load_verify_locations(sslContext, null, getenv(X509_get_default_cert_dir_env()?.toKString())?.toKString()) != 1) { - throw Exception("Server certificate path not found") + if (!tlsSettings.checkServerCertificate) { + SSL_CTX_set_cert_verify_callback( + sslContext, + staticCFunction { buf: CPointer<X509_STORE_CTX>?, arg: COpaquePointer? -> + 1 + }, + null + ) + } else { + if (SSL_CTX_load_verify_locations(sslContext, null, getenv(X509_get_default_cert_dir_env()?.toKString())?.toKString()) != 1) { + throw Exception("Server certificate path not found") + } } } diff --git a/kmqtt-client/src/tvosX64Main/kotlin/TLSClientEngine.kt b/kmqtt-client/src/tvosX64Main/kotlin/TLSClientEngine.kt index d5e331b30bb2dd0e5150a51348b43be5a8f3b858..b180dea3fb966b42a150ca3e66decb194b6cd0f3 100644 --- a/kmqtt-client/src/tvosX64Main/kotlin/TLSClientEngine.kt +++ b/kmqtt-client/src/tvosX64Main/kotlin/TLSClientEngine.kt @@ -69,8 +69,18 @@ internal actual class TLSClientEngine actual constructor(tlsSettings: TLSClientS } } } else { - if (SSL_CTX_load_verify_locations(sslContext, null, getenv(X509_get_default_cert_dir_env()?.toKString())?.toKString()) != 1) { - throw Exception("Server certificate path not found") + if (!tlsSettings.checkServerCertificate) { + SSL_CTX_set_cert_verify_callback( + sslContext, + staticCFunction { buf: CPointer<X509_STORE_CTX>?, arg: COpaquePointer? -> + 1 + }, + null + ) + } else { + if (SSL_CTX_load_verify_locations(sslContext, null, getenv(X509_get_default_cert_dir_env()?.toKString())?.toKString()) != 1) { + throw Exception("Server certificate path not found") + } } } diff --git a/kmqtt-client/src/watchosArm32Main/kotlin/TLSClientEngine.kt b/kmqtt-client/src/watchosArm32Main/kotlin/TLSClientEngine.kt index d5e331b30bb2dd0e5150a51348b43be5a8f3b858..b180dea3fb966b42a150ca3e66decb194b6cd0f3 100644 --- a/kmqtt-client/src/watchosArm32Main/kotlin/TLSClientEngine.kt +++ b/kmqtt-client/src/watchosArm32Main/kotlin/TLSClientEngine.kt @@ -69,8 +69,18 @@ internal actual class TLSClientEngine actual constructor(tlsSettings: TLSClientS } } } else { - if (SSL_CTX_load_verify_locations(sslContext, null, getenv(X509_get_default_cert_dir_env()?.toKString())?.toKString()) != 1) { - throw Exception("Server certificate path not found") + if (!tlsSettings.checkServerCertificate) { + SSL_CTX_set_cert_verify_callback( + sslContext, + staticCFunction { buf: CPointer<X509_STORE_CTX>?, arg: COpaquePointer? -> + 1 + }, + null + ) + } else { + if (SSL_CTX_load_verify_locations(sslContext, null, getenv(X509_get_default_cert_dir_env()?.toKString())?.toKString()) != 1) { + throw Exception("Server certificate path not found") + } } } diff --git a/kmqtt-client/src/watchosArm64Main/kotlin/TLSClientEngine.kt b/kmqtt-client/src/watchosArm64Main/kotlin/TLSClientEngine.kt index d5e331b30bb2dd0e5150a51348b43be5a8f3b858..b180dea3fb966b42a150ca3e66decb194b6cd0f3 100644 --- a/kmqtt-client/src/watchosArm64Main/kotlin/TLSClientEngine.kt +++ b/kmqtt-client/src/watchosArm64Main/kotlin/TLSClientEngine.kt @@ -69,8 +69,18 @@ internal actual class TLSClientEngine actual constructor(tlsSettings: TLSClientS } } } else { - if (SSL_CTX_load_verify_locations(sslContext, null, getenv(X509_get_default_cert_dir_env()?.toKString())?.toKString()) != 1) { - throw Exception("Server certificate path not found") + if (!tlsSettings.checkServerCertificate) { + SSL_CTX_set_cert_verify_callback( + sslContext, + staticCFunction { buf: CPointer<X509_STORE_CTX>?, arg: COpaquePointer? -> + 1 + }, + null + ) + } else { + if (SSL_CTX_load_verify_locations(sslContext, null, getenv(X509_get_default_cert_dir_env()?.toKString())?.toKString()) != 1) { + throw Exception("Server certificate path not found") + } } } diff --git a/kmqtt-client/src/watchosSimulatorArm64Main/kotlin/TLSClientEngine.kt b/kmqtt-client/src/watchosSimulatorArm64Main/kotlin/TLSClientEngine.kt index d5e331b30bb2dd0e5150a51348b43be5a8f3b858..b180dea3fb966b42a150ca3e66decb194b6cd0f3 100644 --- a/kmqtt-client/src/watchosSimulatorArm64Main/kotlin/TLSClientEngine.kt +++ b/kmqtt-client/src/watchosSimulatorArm64Main/kotlin/TLSClientEngine.kt @@ -69,8 +69,18 @@ internal actual class TLSClientEngine actual constructor(tlsSettings: TLSClientS } } } else { - if (SSL_CTX_load_verify_locations(sslContext, null, getenv(X509_get_default_cert_dir_env()?.toKString())?.toKString()) != 1) { - throw Exception("Server certificate path not found") + if (!tlsSettings.checkServerCertificate) { + SSL_CTX_set_cert_verify_callback( + sslContext, + staticCFunction { buf: CPointer<X509_STORE_CTX>?, arg: COpaquePointer? -> + 1 + }, + null + ) + } else { + if (SSL_CTX_load_verify_locations(sslContext, null, getenv(X509_get_default_cert_dir_env()?.toKString())?.toKString()) != 1) { + throw Exception("Server certificate path not found") + } } } diff --git a/kmqtt-client/src/watchosX64Main/kotlin/TLSClientEngine.kt b/kmqtt-client/src/watchosX64Main/kotlin/TLSClientEngine.kt index d5e331b30bb2dd0e5150a51348b43be5a8f3b858..b180dea3fb966b42a150ca3e66decb194b6cd0f3 100644 --- a/kmqtt-client/src/watchosX64Main/kotlin/TLSClientEngine.kt +++ b/kmqtt-client/src/watchosX64Main/kotlin/TLSClientEngine.kt @@ -69,8 +69,18 @@ internal actual class TLSClientEngine actual constructor(tlsSettings: TLSClientS } } } else { - if (SSL_CTX_load_verify_locations(sslContext, null, getenv(X509_get_default_cert_dir_env()?.toKString())?.toKString()) != 1) { - throw Exception("Server certificate path not found") + if (!tlsSettings.checkServerCertificate) { + SSL_CTX_set_cert_verify_callback( + sslContext, + staticCFunction { buf: CPointer<X509_STORE_CTX>?, arg: COpaquePointer? -> + 1 + }, + null + ) + } else { + if (SSL_CTX_load_verify_locations(sslContext, null, getenv(X509_get_default_cert_dir_env()?.toKString())?.toKString()) != 1) { + throw Exception("Server certificate path not found") + } } } diff --git a/kmqtt-common/src/commonMain/kotlin/socket/tls/TLSClientSettings.kt b/kmqtt-common/src/commonMain/kotlin/socket/tls/TLSClientSettings.kt index 03d0c69ed4359e297cf7cf9b5e02b9af08e373e6..9537a62c6e76e6beaf64a23e7d83797e1757d7ff 100644 --- a/kmqtt-common/src/commonMain/kotlin/socket/tls/TLSClientSettings.kt +++ b/kmqtt-common/src/commonMain/kotlin/socket/tls/TLSClientSettings.kt @@ -18,5 +18,6 @@ public data class TLSClientSettings( val serverCertificate: String? = null, val clientCertificate: String? = null, val clientCertificateKey: String? = null, - val clientCertificatePassword: String? = null + val clientCertificatePassword: String? = null, + val checkServerCertificate: Boolean = true )