Skip to content

Commit

Permalink
Merge pull request #3349 from armanbilge/fix/native-mtls
Browse files Browse the repository at this point in the history
Default `client_auth_type = optional` for TLS clients on Native
  • Loading branch information
mpilquist authored Dec 23, 2023
2 parents 871e16a + f1c0460 commit 2161daf
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 4 deletions.
4 changes: 4 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,10 @@ ThisBuild / mimaBinaryIssueFilters ++= Seq(
// package-private method: #3318
ProblemFilters.exclude[IncompatibleMethTypeProblem](
"fs2.io.package.readInputStreamGeneric"
),
// sealed trait: #3349
ProblemFilters.exclude[ReversedMissingMethodProblem](
"fs2.io.net.tls.TLSParameters.withClientAuthType"
)
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,11 @@ private[tls] trait TLSContextCompanionPlatform { self: TLSContext.type =>
logger: TLSLogger[F]
): Resource[F, TLSSocket[F]] = {
val _ = logger
S2nConnection(socket, clientMode, cfg, params).flatMap(TLSSocket(socket, _))
val newParams =
if (clientMode) // cooperate with mTLS if the server requests it
params.withClientAuthType(params.clientAuthType.orElse(Some(CertAuthType.Optional)))
else params
S2nConnection(socket, clientMode, cfg, newParams).flatMap(TLSSocket(socket, _))
}
}
}
Expand Down
7 changes: 6 additions & 1 deletion io/native/src/main/scala/fs2/io/net/tls/TLSParameters.scala
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ sealed trait TLSParameters {
val verifyHostCallback: Option[String => SyncIO[Boolean]]
val clientAuthType: Option[CertAuthType]

private[tls] def withClientAuthType(clientAuthType: Option[CertAuthType]): TLSParameters

private[tls] def configure[F[_]](
conn: Ptr[s2n_connection]
)(implicit F: Sync[F]): Resource[F, Unit] =
Expand Down Expand Up @@ -123,6 +125,9 @@ object TLSParameters {
serverName: Option[String],
verifyHostCallback: Option[String => SyncIO[Boolean]],
clientAuthType: Option[CertAuthType]
) extends TLSParameters
) extends TLSParameters {
def withClientAuthType(clientAuthType: Option[CertAuthType]) =
copy(clientAuthType = clientAuthType)
}

}
47 changes: 45 additions & 2 deletions io/native/src/test/scala/fs2/io/net/tls/TLSSocketSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ class TLSSocketSuite extends TLSSuite {
.intercept[SSLException]
}

test("mTLS client verification") {
test("mTLS client verification fails if client cannot authenticate") {
val msg = Chunk.array(("Hello, world! " * 100).getBytes)

val setup = for {
Expand Down Expand Up @@ -242,13 +242,56 @@ class TLSSocketSuite extends TLSSuite {
clientSocket.reads.take(msg.size.toLong)
}

client.concurrently(echoServer)
client.mask //
.concurrently(echoServer)
}
.compile
.to(Chunk)
.intercept[SSLException]
}

test("mTLS client verification happy-path") {
val msg = Chunk.array(("Hello, world! " * 100).getBytes)

val setup = for {
tlsContext <- testTlsContext
addressAndConnections <- Network[IO].serverResource(Some(ip"127.0.0.1"))
(serverAddress, server) = addressAndConnections
client = Network[IO]
.client(serverAddress)
.flatMap(
tlsContext
.clientBuilder(_)
.withParameters(TLSParameters(serverName = Some("Unknown")))
.build
)
} yield server.flatMap(s =>
Stream.resource(
tlsContext
.serverBuilder(s)
.withParameters(TLSParameters(clientAuthType = CertAuthType.Required.some)) // mTLS
.build
)
) -> client

Stream
.resource(setup)
.flatMap { case (server, clientSocket) =>
val echoServer = server.map { socket =>
socket.reads.chunks.foreach(socket.write(_))
}.parJoinUnbounded

val client = Stream.resource(clientSocket).flatMap { clientSocket =>
Stream.exec(clientSocket.write(msg)) ++
clientSocket.reads.take(msg.size.toLong)
}

client.concurrently(echoServer)
}
.compile
.to(Chunk)
}

test("echo insecure client") {
val msg = Chunk.array(("Hello, world! " * 20000).getBytes)

Expand Down

0 comments on commit 2161daf

Please sign in to comment.