Skip to content

Commit

Permalink
chore: support mtls settings (zio#2443)
Browse files Browse the repository at this point in the history
  • Loading branch information
rajcspsg authored Dec 21, 2023
1 parent 39ec0b5 commit a74ffc0
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 27 deletions.
59 changes: 47 additions & 12 deletions zio-http/src/main/scala/zio/http/SSLConfig.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,32 @@
package zio.http

import zio.Config
import zio.stacktracer.TracingImplicits.disableAutoTrace

import zio.http.SSLConfig._

final case class SSLConfig(behaviour: HttpBehaviour, data: Data, provider: Provider)
sealed trait ClientAuth

object ClientAuth {
case object Required extends ClientAuth
case object NoneClientAuth extends ClientAuth
case object Optional extends ClientAuth

}

final case class SSLConfig(
behaviour: HttpBehaviour,
data: Data,
provider: Provider,
clientAuth: Option[ClientAuth] = None,
)

object SSLConfig {

def apply(data: Data): SSLConfig =
new SSLConfig(HttpBehaviour.Redirect, data, Provider.JDK)
new SSLConfig(HttpBehaviour.Redirect, data, Provider.JDK, None)

def apply(data: Data, clientAuth: ClientAuth): SSLConfig =
new SSLConfig(HttpBehaviour.Redirect, data, Provider.JDK, Some(clientAuth))

val config: Config[SSLConfig] =
(
Expand All @@ -38,22 +54,41 @@ object SSLConfig {
}

def fromFile(certPath: String, keyPath: String): SSLConfig =
new SSLConfig(HttpBehaviour.Redirect, Data.FromFile(certPath, keyPath), Provider.JDK)
fromFile(HttpBehaviour.Redirect, certPath, keyPath)

def fromFile(certPath: String, keyPath: String, clientAuth: ClientAuth): SSLConfig =
fromFile(HttpBehaviour.Redirect, certPath, keyPath, Some(clientAuth))

def fromFile(behaviour: HttpBehaviour, certPath: String, keyPath: String): SSLConfig =
new SSLConfig(behaviour, Data.FromFile(certPath, keyPath), Provider.JDK)
def fromFile(
behaviour: HttpBehaviour,
certPath: String,
keyPath: String,
clientAuth: Option[ClientAuth] = None,
): SSLConfig =
new SSLConfig(behaviour, Data.FromFile(certPath, keyPath), Provider.JDK, clientAuth)

def fromResource(certPath: String, keyPath: String): SSLConfig =
new SSLConfig(HttpBehaviour.Redirect, Data.FromResource(certPath, keyPath), Provider.JDK)
fromResource(HttpBehaviour.Redirect, certPath, keyPath, None)

def fromResource(behaviour: HttpBehaviour, certPath: String, keyPath: String): SSLConfig =
new SSLConfig(behaviour, Data.FromResource(certPath, keyPath), Provider.JDK)
def fromResource(certPath: String, keyPath: String, clientAuth: ClientAuth): SSLConfig =
fromResource(HttpBehaviour.Redirect, certPath, keyPath, Some(clientAuth))

def fromResource(
behaviour: HttpBehaviour,
certPath: String,
keyPath: String,
clientAuth: Option[ClientAuth] = None,
): SSLConfig =
new SSLConfig(behaviour, Data.FromResource(certPath, keyPath), Provider.JDK, clientAuth)

def generate: SSLConfig =
new SSLConfig(HttpBehaviour.Redirect, Data.Generate, Provider.JDK)
generate(HttpBehaviour.Redirect, None)

def generate(clientAuth: ClientAuth): SSLConfig =
generate(HttpBehaviour.Redirect, Some(clientAuth))

def generate(behaviour: HttpBehaviour): SSLConfig =
new SSLConfig(behaviour, Data.Generate, Provider.JDK)
def generate(behaviour: HttpBehaviour, clientAuth: Option[ClientAuth] = None): SSLConfig =
new SSLConfig(behaviour, Data.Generate, Provider.JDK, clientAuth)

sealed trait HttpBehaviour
object HttpBehaviour {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,9 @@ package zio.http.netty.server
import java.io.FileInputStream
import java.util

import zio.stacktracer.TracingImplicits.disableAutoTrace

import zio.http.SSLConfig.{HttpBehaviour, Provider}
import zio.http.netty.Names
import zio.http.{SSLConfig, Server}
import zio.http.{ClientAuth, SSLConfig, Server}

import io.netty.buffer.ByteBuf
import io.netty.channel.ChannelHandlerContext
Expand All @@ -33,27 +31,38 @@ import io.netty.handler.ssl.ApplicationProtocolConfig.{
SelectedListenerFailureBehavior,
SelectorFailureBehavior,
}
import io.netty.handler.ssl._
import io.netty.handler.ssl.util.SelfSignedCertificate
import io.netty.handler.ssl.{SslContext, SslHandler, _}
import io.netty.handler.ssl.{ClientAuth => NettyClientAuth}
object SSLUtil {

def getClientAuth(clientAuth: ClientAuth): NettyClientAuth = clientAuth match {
case ClientAuth.Required => NettyClientAuth.REQUIRE
case ClientAuth.Optional => NettyClientAuth.OPTIONAL
case _ => NettyClientAuth.NONE
}

implicit class SslContextBuilderOps(self: SslContextBuilder) {
def toNettyProvider(sslProvider: Provider): SslProvider = sslProvider match {
case Provider.OpenSSL => SslProvider.OPENSSL
case Provider.JDK => SslProvider.JDK
}

def buildWithDefaultOptions(sslConfig: SSLConfig): SslContext = self
.sslProvider(toNettyProvider(sslConfig.provider))
.applicationProtocolConfig(
new ApplicationProtocolConfig(
Protocol.ALPN,
SelectorFailureBehavior.NO_ADVERTISE,
SelectedListenerFailureBehavior.ACCEPT,
ApplicationProtocolNames.HTTP_1_1,
),
)
.build()
def buildWithDefaultOptions(sslConfig: SSLConfig): SslContext = {
val clientAuthConfig: Option[ClientAuth] = sslConfig.clientAuth
clientAuthConfig.foreach(ca => self.clientAuth(getClientAuth(ca)))
self
.sslProvider(toNettyProvider(sslConfig.provider))
.applicationProtocolConfig(
new ApplicationProtocolConfig(
Protocol.ALPN,
SelectorFailureBehavior.NO_ADVERTISE,
SelectedListenerFailureBehavior.ACCEPT,
ApplicationProtocolNames.HTTP_1_1,
),
)
.build()
}
}

def sslConfigToSslContext(sslConfig: SSLConfig): SslContext = sslConfig.data match {
Expand Down

0 comments on commit a74ffc0

Please sign in to comment.