Skip to content

Commit 0b3124f

Browse files
committed
grpc-native: Working custom TLS credentials
Signed-off-by: Johannes Zottele <[email protected]>
1 parent 9318ec7 commit 0b3124f

File tree

13 files changed

+386
-63
lines changed

13 files changed

+386
-63
lines changed

grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/GrpcClient.kt

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,14 @@ import kotlinx.rpc.grpc.codec.ThrowingMessageCodecResolver
1313
import kotlinx.rpc.grpc.codec.plus
1414
import kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate
1515
import kotlinx.rpc.grpc.descriptor.GrpcServiceDescriptor
16-
import kotlinx.rpc.grpc.internal.*
16+
import kotlinx.rpc.grpc.internal.GrpcDefaultCallOptions
17+
import kotlinx.rpc.grpc.internal.MethodDescriptor
18+
import kotlinx.rpc.grpc.internal.MethodType
19+
import kotlinx.rpc.grpc.internal.bidirectionalStreamingRpc
20+
import kotlinx.rpc.grpc.internal.clientStreamingRpc
21+
import kotlinx.rpc.grpc.internal.serverStreamingRpc
22+
import kotlinx.rpc.grpc.internal.type
23+
import kotlinx.rpc.grpc.internal.unaryRpc
1724
import kotlinx.rpc.internal.utils.map.RpcInternalConcurrentHashMap
1825
import kotlin.time.Duration
1926

@@ -124,10 +131,11 @@ public class GrpcClient internal constructor(
124131
public fun GrpcClient(
125132
hostname: String,
126133
port: Int,
134+
credentials: ChannelCredentials? = null,
127135
messageCodecResolver: MessageCodecResolver = EmptyMessageCodecResolver,
128136
configure: ManagedChannelBuilder<*>.() -> Unit = {},
129137
): GrpcClient {
130-
val channel = ManagedChannelBuilder(hostname, port).apply(configure).buildChannel()
138+
val channel = ManagedChannelBuilder(hostname, port, credentials).apply(configure).buildChannel()
131139
return GrpcClient(channel, messageCodecResolver)
132140
}
133141

@@ -136,9 +144,10 @@ public fun GrpcClient(
136144
*/
137145
public fun GrpcClient(
138146
target: String,
147+
credentials: ChannelCredentials? = null,
139148
messageCodecResolver: MessageCodecResolver = EmptyMessageCodecResolver,
140149
configure: ManagedChannelBuilder<*>.() -> Unit = {},
141150
): GrpcClient {
142-
val channel = ManagedChannelBuilder(target).apply(configure).buildChannel()
151+
val channel = ManagedChannelBuilder(target, credentials).apply(configure).buildChannel()
143152
return GrpcClient(channel, messageCodecResolver)
144153
}

grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/GrpcServer.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import kotlinx.coroutines.Job
1010
import kotlinx.coroutines.SupervisorJob
1111
import kotlinx.coroutines.cancel
1212
import kotlinx.coroutines.flow.Flow
13-
import kotlinx.coroutines.job
1413
import kotlinx.rpc.RpcServer
1514
import kotlinx.rpc.descriptor.RpcCallable
1615
import kotlinx.rpc.descriptor.flowInvokator
@@ -49,6 +48,7 @@ private typealias ResponseServer = Any
4948
*/
5049
public class GrpcServer internal constructor(
5150
override val port: Int = 8080,
51+
credentials: ServerCredentials? = null,
5252
messageCodecResolver: MessageCodecResolver = EmptyMessageCodecResolver,
5353
parentContext: CoroutineContext = EmptyCoroutineContext,
5454
configure: ServerBuilder<*>.() -> Unit,
@@ -61,7 +61,7 @@ public class GrpcServer internal constructor(
6161
private var isBuilt = false
6262
private lateinit var internalServer: Server
6363

64-
private val serverBuilder: ServerBuilder<*> = ServerBuilder(port).apply(configure)
64+
private val serverBuilder: ServerBuilder<*> = ServerBuilder(port, credentials).apply(configure)
6565
private val registry: MutableHandlerRegistry by lazy {
6666
MutableHandlerRegistry().apply { serverBuilder.fallbackHandlerRegistry(this) }
6767
}
@@ -192,10 +192,12 @@ public class GrpcServer internal constructor(
192192
*/
193193
public fun GrpcServer(
194194
port: Int,
195+
credentials: ServerCredentials? = null,
195196
messageCodecResolver: MessageCodecResolver = EmptyMessageCodecResolver,
196197
parentContext: CoroutineContext = EmptyCoroutineContext,
197198
configure: ServerBuilder<*>.() -> Unit = {},
198199
builder: RpcServer.() -> Unit = {},
199200
): GrpcServer {
200-
return GrpcServer(port, messageCodecResolver, parentContext, configure).apply(builder).apply { build() }
201+
return GrpcServer(port, credentials, messageCodecResolver, parentContext, configure).apply(builder)
202+
.apply { build() }
201203
}

grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/ManagedChannel.kt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,15 @@ public expect abstract class ManagedChannelBuilder<T : ManagedChannelBuilder<T>>
7171
public fun usePlaintext(): T
7272
}
7373

74-
internal expect fun ManagedChannelBuilder(hostname: String, port: Int): ManagedChannelBuilder<*>
75-
internal expect fun ManagedChannelBuilder(target: String): ManagedChannelBuilder<*>
74+
internal expect fun ManagedChannelBuilder(
75+
hostname: String,
76+
port: Int,
77+
credentials: ChannelCredentials? = null,
78+
): ManagedChannelBuilder<*>
79+
80+
internal expect fun ManagedChannelBuilder(
81+
target: String,
82+
credentials: ChannelCredentials? = null,
83+
): ManagedChannelBuilder<*>
7684

7785
internal expect fun ManagedChannelBuilder<*>.buildChannel(): ManagedChannel

grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/Server.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public expect abstract class ServerBuilder<T : ServerBuilder<T>> {
3131
public abstract fun fallbackHandlerRegistry(registry: HandlerRegistry?): T
3232
}
3333

34-
internal expect fun ServerBuilder(port: Int): ServerBuilder<*>
34+
internal expect fun ServerBuilder(port: Int, credentials: ServerCredentials? = null): ServerBuilder<*>
3535

3636
/**
3737
* Server for listening for and dispatching incoming calls.

grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/credentials.kt

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,27 @@ package kotlinx.rpc.grpc/*
77
*/
88

99
public expect abstract class ChannelCredentials
10+
public expect abstract class ServerCredentials
1011

1112
public expect class InsecureChannelCredentials : ChannelCredentials
13+
public expect class InsecureServerCredentials : ServerCredentials
1214

1315
public expect class TlsChannelCredentials : ChannelCredentials
16+
public expect class TlsServerCredentials : ServerCredentials
1417

18+
public expect fun TlsChannelCredentials(): ChannelCredentials
19+
public expect fun TlsServerCredentials(certChain: String, privateKey: String): ServerCredentials
1520

16-
public expect fun InsecureChannelCredentials(): ChannelCredentials
17-
public expect fun TlsChannelCredentials(): ChannelCredentials
21+
public interface TlsChannelCredentialsBuilder {
22+
public fun trustManager(rootCertsPem: String): TlsChannelCredentialsBuilder
23+
public fun build(): ChannelCredentials
24+
}
25+
26+
public interface TlsServerCredentialsBuilder {
27+
public fun keyManager(certChainPem: String, privateKeyPem: String): TlsServerCredentialsBuilder
28+
public fun build(): ServerCredentials
29+
}
30+
31+
32+
public expect fun TlsChannelCredentialsBuilder(): TlsChannelCredentialsBuilder
33+
public expect fun TlsServerCredentialsBuilder(): TlsServerCredentialsBuilder

grpc/grpc-core/src/commonTest/kotlin/kotlinx/rpc/grpc/test/proto/GrpcbInTlsTest.kt

Lines changed: 143 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,26 @@ import hello.HelloService
99
import hello.invoke
1010
import kotlinx.coroutines.test.runTest
1111
import kotlinx.rpc.grpc.GrpcClient
12-
import kotlinx.rpc.grpc.TlsChannelCredentials
12+
import kotlinx.rpc.grpc.GrpcServer
13+
import kotlinx.rpc.grpc.TlsChannelCredentialsBuilder
14+
import kotlinx.rpc.grpc.TlsServerCredentialsBuilder
15+
import kotlinx.rpc.grpc.test.EchoRequest
16+
import kotlinx.rpc.grpc.test.EchoService
17+
import kotlinx.rpc.grpc.test.EchoServiceImpl
18+
import kotlinx.rpc.grpc.test.invoke
19+
import kotlinx.rpc.registerService
1320
import kotlinx.rpc.withService
1421
import kotlin.test.Test
1522

23+
private const val PORT = 50051
1624

1725
class GrpcbInTlsTest {
1826

19-
val grpcClient = GrpcClient("grpcb.in", 9001) {
20-
// usePlaintext()
21-
}
2227

2328
@Test
2429
fun testTlsCall() = runTest {
30+
val grpcClient = GrpcClient("grpcb.in", 9001)
2531
val service = grpcClient.withService<HelloService>()
26-
27-
TlsChannelCredentials.create()
28-
2932
val request = HelloRequest {
3033
greeting = "Postman"
3134
}
@@ -35,4 +38,137 @@ class GrpcbInTlsTest {
3538
}
3639

3740

41+
@Test
42+
fun testLocalTls() = runTest {
43+
val serverTls = TlsServerCredentialsBuilder()
44+
.keyManager(SERVER_CERT_PEM, SERVER_KEY_PEM)
45+
.build()
46+
47+
val grpcServer = GrpcServer(
48+
PORT,
49+
credentials = serverTls,
50+
builder = {
51+
registerService<EchoService> { EchoServiceImpl() }
52+
})
53+
grpcServer.start()
54+
55+
val clientTls = TlsChannelCredentialsBuilder()
56+
.trustManager(SERVER_CERT_PEM)
57+
.build()
58+
59+
val grpcClient = GrpcClient(
60+
"localhost", PORT,
61+
credentials = clientTls,
62+
) {}
63+
64+
val service = grpcClient.withService<EchoService>()
65+
val request = EchoRequest {
66+
message = "Postman"
67+
}
68+
69+
try {
70+
service.UnaryEcho(request)
71+
} catch (t: Throwable) {
72+
println("[DEBUG_LOG] TLS test failed: ${t::class.simpleName}: ${t.message}")
73+
t.printStackTrace()
74+
throw t
75+
} finally {
76+
grpcServer.shutdown()
77+
grpcServer.awaitTermination()
78+
grpcClient.shutdown()
79+
grpcClient.awaitTermination()
80+
}
81+
}
82+
83+
84+
private val SERVER_CERT_PEM = """
85+
-----BEGIN CERTIFICATE-----
86+
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
115+
ubFotuU6gIPvra9MI/NUSpA=
116+
-----END CERTIFICATE-----
117+
""".trimIndent()
118+
119+
private val SERVER_KEY_PEM = """
120+
-----BEGIN PRIVATE KEY-----
121+
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
170+
paLEjX+8kznUisDokSzJ7iHoZgmN
171+
-----END PRIVATE KEY-----
172+
""".trimIndent()
173+
38174
}

grpc/grpc-core/src/jvmMain/kotlin/kotlinx/rpc/grpc/ManagedChannel.jvm.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,20 @@ internal actual fun ManagedChannelBuilder<*>.buildChannel(): ManagedChannel {
2424
return build().toKotlin()
2525
}
2626

27-
internal actual fun ManagedChannelBuilder(hostname: String, port: Int): ManagedChannelBuilder<*> {
27+
internal actual fun ManagedChannelBuilder(
28+
hostname: String,
29+
port: Int,
30+
credentials: ChannelCredentials?,
31+
): ManagedChannelBuilder<*> {
32+
if (credentials != null) return io.grpc.Grpc.newChannelBuilderForAddress(hostname, port, credentials)
2833
return io.grpc.ManagedChannelBuilder.forAddress(hostname, port)
2934
}
3035

3136
internal actual fun ManagedChannelBuilder(
3237
target: String,
38+
credentials: ChannelCredentials?,
3339
): ManagedChannelBuilder<*> {
40+
if (credentials != null) return io.grpc.Grpc.newChannelBuilder(target, credentials)
3441
return io.grpc.ManagedChannelBuilder.forTarget(target)
3542
}
3643

grpc/grpc-core/src/jvmMain/kotlin/kotlinx/rpc/grpc/Server.jvm.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ import kotlin.time.Duration
1414
*/
1515
public actual typealias ServerBuilder<T> = io.grpc.ServerBuilder<T>
1616

17-
internal actual fun ServerBuilder(port: Int): ServerBuilder<*> {
17+
internal actual fun ServerBuilder(port: Int, credentials: ServerCredentials?): ServerBuilder<*> {
18+
if (credentials != null) return io.grpc.Grpc.newServerBuilderForPort(port, credentials)
1819
return io.grpc.ServerBuilder.forPort(port)
1920
}
2021

0 commit comments

Comments
 (0)