From 3f0c02852a0923f89ecc42f6e01ce8a9b8b5cb63 Mon Sep 17 00:00:00 2001 From: Topias Jokiniemi <117648262+topiasjokiniemi-nordic@users.noreply.github.com> Date: Wed, 19 Jul 2023 12:46:30 +0300 Subject: [PATCH] Make cid accessible from DtslServer (#26) * make cid accessible from DtslServer * cleaning. Added get cid to DtslServerTransport as well * executor for get cid --- .../org/opencoap/ssl/transport/DtlsServer.kt | 7 ++++- .../ssl/transport/DtlsServerTransport.kt | 2 ++ .../ssl/transport/DtlsSessionContext.kt | 26 ++++++++++++++++++- .../opencoap/ssl/transport/DtlsServerTest.kt | 19 +++++++++++++- .../ssl/transport/DtlsServerTransportTest.kt | 14 ++++++++-- 5 files changed, 63 insertions(+), 5 deletions(-) diff --git a/kotlin-mbedtls/src/main/kotlin/org/opencoap/ssl/transport/DtlsServer.kt b/kotlin-mbedtls/src/main/kotlin/org/opencoap/ssl/transport/DtlsServer.kt index 59999b38..0c2a63fc 100644 --- a/kotlin-mbedtls/src/main/kotlin/org/opencoap/ssl/transport/DtlsServer.kt +++ b/kotlin-mbedtls/src/main/kotlin/org/opencoap/ssl/transport/DtlsServer.kt @@ -50,6 +50,10 @@ class DtlsServer( private val sessions = mutableMapOf() private val cidSize = sslConfig.cidSupplier.next().size val numberOfSessions get() = sessions.size + fun getSessionCid(inet: InetSocketAddress): ByteArray? { + val dtlsState = sessions[inet] as? DtlsSession + return dtlsState?.sessionContext?.cid + } fun handleReceived(adr: InetSocketAddress, buf: ByteBuffer): ReceiveResult { val cid by lazy { SslContext.peekCID(cidSize, buf) } @@ -215,7 +219,8 @@ class DtlsServer( val sessionContext: DtlsSessionContext get() = DtlsSessionContext( peerCertificateSubject = ctx.peerCertificateSubject, - authenticationContext = authenticationContext + authenticationContext = authenticationContext, + cid = if (ctx.ownCid?.isEmpty() != true) ctx.ownCid else ctx.peerCid ) init { diff --git a/kotlin-mbedtls/src/main/kotlin/org/opencoap/ssl/transport/DtlsServerTransport.kt b/kotlin-mbedtls/src/main/kotlin/org/opencoap/ssl/transport/DtlsServerTransport.kt index 5ca80aa7..ab60541e 100644 --- a/kotlin-mbedtls/src/main/kotlin/org/opencoap/ssl/transport/DtlsServerTransport.kt +++ b/kotlin-mbedtls/src/main/kotlin/org/opencoap/ssl/transport/DtlsServerTransport.kt @@ -114,4 +114,6 @@ class DtlsServerTransport private constructor( executor.supply { dtlsServer.putSessionAuthenticationContext(adr, key, value) } + + fun getSessionCid(adr: InetSocketAddress) = executor.supply { dtlsServer.getSessionCid(adr) } } diff --git a/kotlin-mbedtls/src/main/kotlin/org/opencoap/ssl/transport/DtlsSessionContext.kt b/kotlin-mbedtls/src/main/kotlin/org/opencoap/ssl/transport/DtlsSessionContext.kt index e10d0b6e..576c0d95 100644 --- a/kotlin-mbedtls/src/main/kotlin/org/opencoap/ssl/transport/DtlsSessionContext.kt +++ b/kotlin-mbedtls/src/main/kotlin/org/opencoap/ssl/transport/DtlsSessionContext.kt @@ -20,10 +20,34 @@ typealias AuthenticationContext = Map data class DtlsSessionContext @JvmOverloads constructor( val authenticationContext: AuthenticationContext = emptyMap(), - val peerCertificateSubject: String? = null + val peerCertificateSubject: String? = null, + val cid: ByteArray? = null ) { companion object { @JvmField val EMPTY = DtlsSessionContext() } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as DtlsSessionContext + + if (authenticationContext != other.authenticationContext) return false + if (peerCertificateSubject != other.peerCertificateSubject) return false + if (cid != null) { + if (other.cid == null) return false + if (!cid.contentEquals(other.cid)) return false + } else if (other.cid != null) return false + + return true + } + + override fun hashCode(): Int { + var result = authenticationContext.hashCode() + result = 31 * result + (peerCertificateSubject?.hashCode() ?: 0) + result = 31 * result + (cid?.contentHashCode() ?: 0) + return result + } } diff --git a/kotlin-mbedtls/src/test/kotlin/org/opencoap/ssl/transport/DtlsServerTest.kt b/kotlin-mbedtls/src/test/kotlin/org/opencoap/ssl/transport/DtlsServerTest.kt index 87ebd926..d2e76cee 100644 --- a/kotlin-mbedtls/src/test/kotlin/org/opencoap/ssl/transport/DtlsServerTest.kt +++ b/kotlin-mbedtls/src/test/kotlin/org/opencoap/ssl/transport/DtlsServerTest.kt @@ -216,7 +216,6 @@ class DtlsServerTest { // given val clientSession = clientHandshake() assertEquals(1, dtlsServer.numberOfSessions) - // and nothing is sent to server // when, inactivity @@ -227,6 +226,24 @@ class DtlsServerTest { clientSession.close() } + @Test + fun `should find session cid`() { + // given + val clientSession = clientHandshake() + val cid = dtlsServer.getSessionCid(localAddress(2_5684)) + assert(cid!!.isNotEmpty()) + clientSession.close() + } + + @Test + fun `shouldn't find session cid`() { + // given + val clientSession = clientHandshake() + val cid = dtlsServer.getSessionCid(localAddress(1234)) + assertEquals(null, cid) + clientSession.close() + } + private fun clientHandshake(): SslSession { val send: (ByteBuffer) -> Unit = { dtlsServer.handleReceived(localAddress(2_5684), it) } val cliHandshake = clientConf.newContext(localAddress(5684)) diff --git a/kotlin-mbedtls/src/test/kotlin/org/opencoap/ssl/transport/DtlsServerTransportTest.kt b/kotlin-mbedtls/src/test/kotlin/org/opencoap/ssl/transport/DtlsServerTransportTest.kt index 7eb4d150..1c9a04f6 100644 --- a/kotlin-mbedtls/src/test/kotlin/org/opencoap/ssl/transport/DtlsServerTransportTest.kt +++ b/kotlin-mbedtls/src/test/kotlin/org/opencoap/ssl/transport/DtlsServerTransportTest.kt @@ -25,6 +25,7 @@ import org.awaitility.kotlin.await import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertNull import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Test import org.opencoap.ssl.CertificateAuth @@ -438,6 +439,15 @@ class DtlsServerTransportTest { assertTrue(server.executor() is ScheduledThreadPoolExecutor) } + @Test + fun `should not return cid`() { + server = DtlsServerTransport.create(conf, lifecycleCallbacks = sslLifecycleCallbacks).listen(echoHandler) + val client = DtlsTransmitter.connect(server, clientConfig).await() + client.send("hello!") + val cid = server.getSessionCid(localAddress(1234)).await() + assertNull(cid) + } + @Test fun `should set and use session context`() { // given @@ -456,8 +466,8 @@ class DtlsServerTransportTest { client.send("msg2") // then - assertEquals(DtlsSessionContext(mapOf("auth" to "id:dev-007")), server.receive(1.seconds).await().sessionContext) - assertEquals(DtlsSessionContext(mapOf("auth" to "id:dev-007")), server.receive(1.seconds).await().sessionContext) + assertEquals(mapOf("auth" to "id:dev-007"), server.receive(1.seconds).await().sessionContext.authenticationContext) + assertEquals(mapOf("auth" to "id:dev-007"), server.receive(1.seconds).await().sessionContext.authenticationContext) client.close() }