All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.twitter.finagle.ssl.client.SslClientEngineFactory.scala Maven / Gradle / Ivy

There is a newer version: 21.2.0
Show newest version
package com.twitter.finagle.ssl.client

import com.twitter.finagle.{Address, Stack}
import com.twitter.finagle.ssl._
import java.net.InetSocketAddress
import javax.net.ssl.SSLContext

/**
 * Instances of this class provide a method to create Finagle
 * [[Engine Engines]] for use with TLS.
 */
abstract class SslClientEngineFactory {

  /**
   * Creates a new [[Engine]] based on an [[Address]]
   * and a [[SslClientConfiguration]].
   *
   * @param address A physical address which potentially includes
   * metadata.
   *
   * @param config A collection of parameters which the engine factory
   * should consider when creating the TLS client [[Engine]].
   */
  def apply(address: Address, config: SslClientConfiguration): Engine
}

object SslClientEngineFactory {

  /**
   * $param the client engine factory used for creating an [[Engine]]
   * which is used with an SSL/TLS connection.
   *
   * @param factory The [[SslClientEngineFactory]] to use for creating
   * an [[Engine]] based off of an [[Address]] and an [[SslClientConfiguration]].
   *
   * @note By default a [[JdkClientEngineFactory]] will be used if this
   * param is not configured.
   */
  case class Param(factory: SslClientEngineFactory) {
    def mk(): (Param, Stack.Param[Param]) =
      (this, Param.param)
  }
  object Param {
    implicit val param = Stack.Param(Param(JdkClientEngineFactory))
  }

  /**
   * Configure the supplied [[Engine Engine's]] client mode,
   * protocols and cipher suites.
   */
  def configureEngine(engine: Engine, config: SslClientConfiguration): Unit = {
    val sslEngine = engine.self

    // Use true here to ensure that this engine is seen as a client engine.
    // This matters for handshaking.
    sslEngine.setUseClientMode(true)

    SslConfigurations.configureProtocols(sslEngine, config.protocols)
    SslConfigurations.configureCipherSuites(sslEngine, config.cipherSuites)
    SslConfigurations.configureHostnameVerification(sslEngine, config.hostname)
  }

  /**
   * Use the supplied `javax.net.ssl.SSLContext` to create a new
   * [[Engine]] based on a hostname and port, if available.
   */
  def createEngine(
    sslContext: SSLContext,
    address: Address,
    config: SslClientConfiguration
  ): Engine = {
    val sslEngine = address match {
      case Address.Inet(isa, _) =>
        sslContext.createSSLEngine(getHostString(isa, config), isa.getPort)
      case _ => sslContext.createSSLEngine()
    }
    new Engine(sslEngine)
  }

  /**
   * Return the hostname from the [[SslClientConfiguration configuration]] if set,
   * or fall back to the host string of the `java.net.InetSocketAddress`.
   *
   * @note If the config does not contain a hostname, this method will not perform
   * a reverse DNS lookup if the address was created with a literal IP address.
   */
  def getHostString(isa: InetSocketAddress, config: SslClientConfiguration): String =
    config.hostname match {
      case Some(host) => host
      case None => isa.getHostString
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy