javax.net.ssl.SSLContext Scala Examples

The following examples show how to use javax.net.ssl.SSLContext. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example.
Example 1
Source File: SSL.scala    From lolhttp   with Apache License 2.0 6 votes vote down vote up
package lol.http

import java.security.KeyStore
import java.security.SecureRandom
import java.security.cert.X509Certificate
import javax.net.ssl.{SSLContext, KeyManagerFactory, X509TrustManager}


import org.http4s.blaze.util.BogusKeystore


  lazy val selfSigned = new ServerConfiguration({
    val ksStream = BogusKeystore.asInputStream()
    val ks = KeyStore.getInstance("JKS")
    ks.load(ksStream, BogusKeystore.getKeyStorePassword)
    val kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
    kmf.init(ks, BogusKeystore.getCertificatePassword)
    val sslContext = SSLContext.getInstance("SSL")
    sslContext.init(kmf.getKeyManagers(), null, null)
    sslContext
  }, "selfSigned")

} 
Example 2
Source File: TestkitSslSetup.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.lagom.internal.testkit

import javax.net.ssl.SSLContext
import com.lightbend.lagom.devmode.ssl.KeyStoreMetadata

private[lagom] object TestkitSslSetup {
  sealed trait TestkitSslSetup {
    def sslPort: Option[Int]

    def sslSettings: Map[String, AnyRef]

    def clientSslContext: Option[SSLContext]
  }

  case object Disabled extends TestkitSslSetup {
    val sslPort: Option[Int]                 = None
    val sslSettings: Map[String, AnyRef]     = Map.empty[String, AnyRef]
    val clientSslContext: Option[SSLContext] = None
  }

  case class Enabled(
      sslPort: Option[Int] = Some(0),
      sslSettings: Map[String, AnyRef],
      clientSslContext: Option[SSLContext]
  ) extends TestkitSslSetup

  val disabled: TestkitSslSetup = Disabled

  
  def enabled(
      keyStoreMetadata: KeyStoreMetadata,
      trustStoreMetadata: KeyStoreMetadata,
      clientSslContext: SSLContext
  ): TestkitSslSetup = {
    val sslSettings: Map[String, AnyRef] = Map(
      // See also play/core/server/devmode/LagomDevModeReloadableServer.scala
      // These configure the server
      "play.server.https.keyStore.path"     -> keyStoreMetadata.storeFile.getAbsolutePath,
      "play.server.https.keyStore.type"     -> keyStoreMetadata.storeType,
      "play.server.https.keyStore.password" -> String.valueOf(keyStoreMetadata.storePassword),
      // These configure the clients (play-ws and akka-grpc)
      "ssl-config.loose.disableHostnameVerification" -> "true",
      "ssl-config.trustManager.stores.0.path"        -> trustStoreMetadata.storeFile.getAbsolutePath,
      "ssl-config.trustManager.stores.0.type"        -> trustStoreMetadata.storeType,
      "ssl-config.trustManager.stores.0.password"    -> String.valueOf(trustStoreMetadata.storePassword)
    )
    Enabled(Some(0), sslSettings, Some(clientSslContext))
  }
} 
Example 3
Source File: TestSSLConfigContext.scala    From kafka-connect-common   with Apache License 2.0 5 votes vote down vote up
package com.datamountaineer.streamreactor.connect.config

import javax.net.ssl.{KeyManager, SSLContext, TrustManager}
import org.scalatest.wordspec.AnyWordSpec
import org.scalatest.BeforeAndAfter
import org.scalatest.matchers.should.Matchers


class TestSSLConfigContext extends AnyWordSpec with Matchers with BeforeAndAfter {
  var sslConfig : SSLConfig = null
  var sslConfigNoClient : SSLConfig = null

  before {
    val trustStorePath = System.getProperty("truststore")
    val trustStorePassword ="erZHDS9Eo0CcNo"
    val keystorePath = System.getProperty("keystore")
    val keystorePassword ="8yJQLUnGkwZxOw"
    sslConfig = SSLConfig(trustStorePath, trustStorePassword , Some(keystorePath), Some(keystorePassword), true)
    sslConfigNoClient = SSLConfig(trustStorePath, trustStorePassword , Some(keystorePath), Some(keystorePassword), false)
  }

  "SSLConfigContext" should {
    "should return an Array of KeyManagers" in {
      val keyManagers = SSLConfigContext.getKeyManagers(sslConfig)
      keyManagers.length shouldBe 1
      val entry = keyManagers.head
      entry shouldBe a [KeyManager]
    }

    "should return an Array of TrustManagers" in {
      val trustManager = SSLConfigContext.getTrustManagers(sslConfig)
      trustManager.length shouldBe 1
      val entry = trustManager.head
      entry shouldBe a [TrustManager]
    }

    "should return a SSLContext" in {
      val context = SSLConfigContext(sslConfig)
      context.getProtocol shouldBe "SSL"
      context shouldBe a [SSLContext]
    }
  }
} 
Example 4
Source File: SslContextModule.scala    From scala-server-toolkit   with MIT License 5 votes vote down vote up
package com.avast.sst.ssl

import cats.effect.Sync
import cats.syntax.functor._
import com.typesafe.config.{Config, ConfigFactory}
import com.typesafe.sslconfig.ssl.{
  ConfigSSLContextBuilder,
  DefaultKeyManagerFactoryWrapper,
  DefaultTrustManagerFactoryWrapper,
  SSLConfigFactory
}
import javax.net.ssl.{KeyManagerFactory, SSLContext, TrustManagerFactory}

object SslContextModule {

  private val SslContextEnabledKey = "enabled"

  
  def makeIfEnabled[F[_]: Sync](config: Config, withReference: Boolean = true): F[Option[SSLContext]] = {
    if (config.hasPath(SslContextEnabledKey) && config.getBoolean(SslContextEnabledKey)) {
      make(config, withReference).map(Some(_))
    } else {
      Sync[F].delay(None)
    }

  }

  private def referenceConfigUnsafe(): Config = ConfigFactory.defaultReference().getConfig("ssl-config")

} 
Example 5
Source File: Http4sBlazeClientModule.scala    From scala-server-toolkit   with MIT License 5 votes vote down vote up
package com.avast.sst.http4s.client

import cats.effect.{ConcurrentEffect, Resource}
import javax.net.ssl.SSLContext
import org.http4s.client.Client
import org.http4s.client.blaze.BlazeClientBuilder

import scala.concurrent.ExecutionContext
object Http4sBlazeClientModule {

  
  def make[F[_]: ConcurrentEffect](
      config: Http4sBlazeClientConfig,
      executionContext: ExecutionContext,
      sslContext: Option[SSLContext] = None
  ): Resource[F, Client[F]] = {
    val builder = BlazeClientBuilder[F](executionContext)
      .withResponseHeaderTimeout(config.responseHeaderTimeout)
      .withIdleTimeout(config.idleTimeout)
      .withRequestTimeout(config.requestTimeout)
      .withConnectTimeout(config.connectTimeout)
      .withUserAgent(config.userAgent)
      .withMaxTotalConnections(config.maxTotalConnections)
      .withMaxWaitQueueLimit(config.maxWaitQueueLimit)
      .withMaxConnectionsPerRequestKey(Function.const(config.maxConnectionsPerRequestkey))
      .withCheckEndpointAuthentication(config.checkEndpointIdentification)
      .withMaxResponseLineSize(config.maxResponseLineSize)
      .withMaxHeaderLength(config.maxHeaderLength)
      .withMaxChunkSize(config.maxChunkSize)
      .withChunkBufferMaxSize(config.chunkBufferMaxSize)
      .withParserMode(config.parserMode)
      .withBufferSize(config.bufferSize)

    sslContext.map(builder.withSslContext).getOrElse(builder).resource
  }

} 
Example 6
Source File: MqttSSLSocketFactory.scala    From stream-reactor   with Apache License 2.0 5 votes vote down vote up
package com.datamountaineer.streamreactor.connect.mqtt.source

import java.io.FileReader
import java.security.{KeyStore, Security}

import com.typesafe.scalalogging.StrictLogging
import javax.net.ssl.{KeyManagerFactory, SSLContext, SSLSocketFactory, TrustManagerFactory}
import org.bouncycastle.cert.X509CertificateHolder
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter
import org.bouncycastle.jce.provider.BouncyCastleProvider
import org.bouncycastle.openssl.jcajce.{JcaPEMKeyConverter, JcePEMDecryptorProviderBuilder}
import org.bouncycastle.openssl.{PEMEncryptedKeyPair, PEMKeyPair, PEMParser}


object MqttSSLSocketFactory extends StrictLogging {
  def apply(caCrtFile: String,
            crtFile: String,
            keyFile: String,
            password: String): SSLSocketFactory = {
    try {

      
      context.getSocketFactory
    }
    catch {
      case e: Exception =>
        logger.warn(e.getMessage, e)
        null
    }
  }
} 
Example 7
Source File: SSLContextProvider.scala    From service-container   with Apache License 2.0 5 votes vote down vote up
package com.github.vonnagy.service.container.security

import javax.net.ssl.SSLContext

import akka.actor.{ActorSystem, ExtendedActorSystem}
import com.github.vonnagy.service.container.log.LoggingAdapter
import com.typesafe.sslconfig.akka.AkkaSSLConfig
import com.typesafe.sslconfig.akka.util.AkkaLoggerFactory
import com.typesafe.sslconfig.ssl.{ConfigSSLContextBuilder, SSLConfigFactory}

trait SSLContextProvider extends LoggingAdapter {

  // The actor system
  implicit def system: ActorSystem
  // The namespace of the SSL configuration
  implicit  def configNamespace: String
  // Is this a client or server SSL configuration
  def isClient: Boolean

  lazy val sslConfig = new AkkaSSLConfig(system.asInstanceOf[ExtendedActorSystem], {
    val containerOverrides = system.settings.config.getConfig(configNamespace)
    val akkaOverrides = system.settings.config.getConfig("akka.ssl-config")
    val defaults = system.settings.config.getConfig("ssl-config")
    SSLConfigFactory.parse(containerOverrides withFallback akkaOverrides withFallback defaults)
  })

  implicit def sslContext = if (sslConfig.config.default) {
    log.info("ssl.default is true, using the JDK's default SSLContext")
    sslConfig.validateDefaultTrustManager(sslConfig.config)
    SSLContext.getDefault
  } else {
    // break out the static methods as much as we can...
    val keyManagerFactory = sslConfig.buildKeyManagerFactory( sslConfig.config)
    val trustManagerFactory = sslConfig.buildTrustManagerFactory( sslConfig.config)
    new ConfigSSLContextBuilder(new AkkaLoggerFactory(system), sslConfig.config, keyManagerFactory, trustManagerFactory).build()
  }
}

trait SSLServerContextProvider extends SSLContextProvider {

  def isClient = false

}

trait SSLClientContextProvider extends SSLContextProvider {

  def isClient = true

} 
Example 8
Source File: SocksProxyChecker.scala    From ProxyCrawler   with Apache License 2.0 5 votes vote down vote up
package org.crowdcrawler.proxycrawler.checker

import java.net
import java.net.{InetSocketAddress, Socket, URI}
import java.nio.charset.StandardCharsets
import javax.net.ssl.{HostnameVerifier, SSLContext}

import org.apache.http.annotation.ThreadSafe
import org.apache.http.client.methods.HttpGet
import org.apache.http.client.protocol.HttpClientContext
import org.apache.http.config.RegistryBuilder
import org.apache.http.conn.socket.{ConnectionSocketFactory, PlainConnectionSocketFactory}
import org.apache.http.conn.ssl.{NoopHostnameVerifier, SSLConnectionSocketFactory}
import org.apache.http.impl.client.HttpClients
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager
import org.apache.http.protocol.HttpContext
import org.apache.http.util.EntityUtils


@ThreadSafe
private[checker] object SocksProxyChecker extends AbstractProxyChecker {
  private class MyHttpConnectionSocketFactory extends PlainConnectionSocketFactory {
    override def createSocket(context: HttpContext): Socket = {
      val socksAddress = context.getAttribute("socks.address").asInstanceOf[InetSocketAddress]
      val proxy = new net.Proxy(net.Proxy.Type.SOCKS, socksAddress)
      new Socket(proxy)
    }
  }

  private class MyHttpsConnectionSocketFactory(sslContext: SSLContext, verifier: HostnameVerifier)
    extends SSLConnectionSocketFactory(sslContext) {
    override def createSocket(context: HttpContext): Socket = {
      val socksAddress = context.getAttribute("socks.address").asInstanceOf[InetSocketAddress]
      val proxy = new net.Proxy(net.Proxy.Type.SOCKS, socksAddress)
      new Socket(proxy)
    }
  }

  private val CLIENT = {
    val reg = RegistryBuilder.create[ConnectionSocketFactory]()
      .register("http", new MyHttpConnectionSocketFactory())
      .register("https",
        new MyHttpsConnectionSocketFactory(HttpsProxyChecker.SSL_CONTEXT, NoopHostnameVerifier.INSTANCE))
      .build()
    val cm = new PoolingHttpClientConnectionManager(reg)
    cm.setMaxTotal(AbstractProxyChecker.MAX_CONN)
    HttpClients.custom().setConnectionManager(cm).disableRedirectHandling().build()
  }
  private val TARGET_URL = new URI("http://www.baidu.com")


  def check(host: String, port: Int): (Int, Int) = {
    val request = new HttpGet(TARGET_URL)
    AbstractProxyChecker.configureRequest(request)

    val httpContext = {
      val socksAddress = new InetSocketAddress(host, port)
      val context = HttpClientContext.create()
      context.setAttribute("socks.address", socksAddress)
      context
    }

    val response = CLIENT.execute(request, httpContext)

    val statusCode = response.getStatusLine.getStatusCode
    val html = EntityUtils.toString(response.getEntity, StandardCharsets.UTF_8)
    if (statusCode == 200 && html.contains("<title>百度一下")) (statusCode, html.getBytes.length) else (statusCode, -1)
  }
} 
Example 9
Source File: ClientFlowHttpsSpec.scala    From squbs   with Apache License 2.0 5 votes vote down vote up
package org.squbs.httpclient

import java.io.InputStream
import java.security.{KeyStore, SecureRandom}
import javax.net.ssl.{KeyManagerFactory, SSLContext, TrustManagerFactory}

import akka.actor.ActorSystem
import akka.http.scaladsl.model._
import akka.http.scaladsl.{ConnectionContext, Http}
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.{Sink, Source}
import akka.util.ByteString
import com.typesafe.config.ConfigFactory
import org.scalatest.{AsyncFlatSpec, BeforeAndAfterAll, Matchers}
import org.squbs.resolver.ResolverRegistry
import org.squbs.testkit.Timeouts._

import scala.concurrent.{Await, Future}
import scala.util.{Success, Try}

object ClientFlowHttpsSpec {

  val config = ConfigFactory.parseString(
    """
      |helloHttps {
      |  type = squbs.httpclient
      |  akka.ssl-config.loose.disableHostnameVerification = true
      |}
    """.stripMargin)

  implicit val system = ActorSystem("ClientFlowHttpsSpec", config)
  implicit val materializer = ActorMaterializer()

  ResolverRegistry(system).register[HttpEndpoint]("LocalhostHttpsEndpointResolver") { (name, _) =>
    name match {
      case "helloHttps" =>
        Some(HttpEndpoint(s"https://localhost:$port", Some(sslContext("exampletrust.jks", "changeit")), None))
      case _ => None
    }
  }

  import akka.http.scaladsl.server.Directives._
  import system.dispatcher

  val route =
    path("hello") {
      get {
        complete(HttpEntity(ContentTypes.`text/html(UTF-8)`, "Hello World!"))
      }
    }

  val serverBinding = Await.result(Http().bindAndHandle(route, "localhost", 0,
    ConnectionContext.https(sslContext("example.com.jks", "changeit"))), awaitMax)
  val port = serverBinding.localAddress.getPort
}

class ClientFlowHttpsSpec  extends AsyncFlatSpec with Matchers with BeforeAndAfterAll {

  import ClientFlowHttpsSpec._

  override def afterAll: Unit = {
    serverBinding.unbind() map {_ => system.terminate()}
  }

  it should "make a call to Hello Service" in {
    val clientFlow = ClientFlow[Int]("helloHttps")
    val responseFuture: Future[(Try[HttpResponse], Int)] =
      Source.single(HttpRequest(uri = "/hello") -> 42)
        .via(clientFlow)
        .runWith(Sink.head)

    val (Success(response), _) = Await.result(responseFuture, awaitMax)
    response.status should be (StatusCodes.OK)
    val entity = response.entity.dataBytes.runFold(ByteString(""))(_ ++ _) map(_.utf8String)
    entity map { e => e shouldEqual "Hello World!" }
  }
} 
Example 10
Source File: SSL.scala    From skunk   with MIT License 5 votes vote down vote up
// Copyright (c) 2018-2020 by Rob Norris
// This software is licensed under the MIT License (MIT).
// For more information see LICENSE or https://opensource.org/licenses/MIT

package skunk

import cats.effect._
import cats.implicits._
import fs2.io.tls.TLSContext
import java.nio.file.Path
import java.security.KeyStore
import javax.net.ssl.SSLContext
import fs2.io.tls.TLSParameters
import skunk.net.SSLNegotiation

sealed abstract class SSL(
  val tlsParameters: TLSParameters = TLSParameters.Default,
  val fallbackOk:    Boolean       = false,
) { outer =>

  def tlsContext[F[_]: Sync: ContextShift](b: Blocker): F[TLSContext]

  def withTLSParameters(tlsParameters: TLSParameters): SSL =
    new SSL(tlsParameters, fallbackOk) {
      def tlsContext[F[_]: Sync: ContextShift](b: Blocker): F[TLSContext] =
        outer.tlsContext(b)
    }

  def withFallback(fallbackOk: Boolean): SSL =
    new SSL(tlsParameters, fallbackOk) {
      def tlsContext[F[_]: Sync: ContextShift](b: Blocker): F[TLSContext] =
        outer.tlsContext(b)
    }

  def toSSLNegotiationOptions[F[_]: Sync: ContextShift](b: Blocker, logger: Option[String => F[Unit]]): F[Option[SSLNegotiation.Options[F]]] =
    this match {
      case SSL.None => none.pure[F]
      case _ => tlsContext(b).map(SSLNegotiation.Options(_, tlsParameters, fallbackOk, logger).some)
    }

}

object SSL {

  
  def fromKeyStore(
      keyStore: KeyStore,
      keyPassword: Array[Char],
  ): SSL =
    new SSL() {
      def tlsContext[F[_]: Sync: ContextShift](b: Blocker): F[TLSContext] =
       TLSContext.fromKeyStore(keyStore, keyPassword, b)
    }

} 
Example 11
Source File: SslContexts.scala    From kubernetes-client   with Apache License 2.0 5 votes vote down vote up
package com.goyeau.kubernetes.client.util
import java.io.{ByteArrayInputStream, File, FileInputStream, InputStreamReader}
import java.security.cert.{CertificateFactory, X509Certificate}
import java.security.{KeyStore, SecureRandom, Security}
import java.util.Base64

import com.goyeau.kubernetes.client.KubeConfig
import javax.net.ssl.{KeyManagerFactory, SSLContext, TrustManagerFactory}
import org.bouncycastle.jce.provider.BouncyCastleProvider
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter
import org.bouncycastle.openssl.{PEMKeyPair, PEMParser}

object SslContexts {
  private val TrustStoreSystemProperty         = "javax.net.ssl.trustStore"
  private val TrustStorePasswordSystemProperty = "javax.net.ssl.trustStorePassword"
  private val KeyStoreSystemProperty           = "javax.net.ssl.keyStore"
  private val KeyStorePasswordSystemProperty   = "javax.net.ssl.keyStorePassword"

  def fromConfig(config: KubeConfig): SSLContext = {
    val sslContext = SSLContext.getInstance("TLS")
    sslContext.init(keyManagers(config), trustManagers(config), new SecureRandom)
    sslContext
  }

  private def keyManagers(config: KubeConfig) = {
    // Client certificate
    val certDataStream = config.clientCertData.map(data => new ByteArrayInputStream(Base64.getDecoder.decode(data)))
    val certFileStream = config.clientCertFile.map(new FileInputStream(_))

    // Client key
    val keyDataStream = config.clientKeyData.map(data => new ByteArrayInputStream(Base64.getDecoder.decode(data)))
    val keyFileStream = config.clientKeyFile.map(new FileInputStream(_))

    for {
      keyStream  <- keyDataStream.orElse(keyFileStream)
      certStream <- certDataStream.orElse(certFileStream)
    } yield {
      Security.addProvider(new BouncyCastleProvider())
      val pemKeyPair =
        new PEMParser(new InputStreamReader(keyStream)).readObject().asInstanceOf[PEMKeyPair] // scalafix:ok
      val privateKey = new JcaPEMKeyConverter().setProvider("BC").getPrivateKey(pemKeyPair.getPrivateKeyInfo)

      val certificateFactory = CertificateFactory.getInstance("X509")
      val certificate        = certificateFactory.generateCertificate(certStream).asInstanceOf[X509Certificate] // scalafix:ok

      defaultKeyStore.setKeyEntry(
        certificate.getSubjectX500Principal.getName,
        privateKey,
        config.clientKeyPass.fold(Array.empty[Char])(_.toCharArray),
        Array(certificate)
      )
    }

    val keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm)
    keyManagerFactory.init(defaultKeyStore, Array.empty)
    keyManagerFactory.getKeyManagers
  }

  private lazy val defaultKeyStore = {
    val propertyKeyStoreFile =
      Option(System.getProperty(KeyStoreSystemProperty, "")).filter(_.nonEmpty).map(new File(_))

    val keyStore = KeyStore.getInstance(KeyStore.getDefaultType)
    keyStore.load(
      propertyKeyStoreFile.map(new FileInputStream(_)).orNull,
      System.getProperty(KeyStorePasswordSystemProperty, "").toCharArray
    )
    keyStore
  }

  private def trustManagers(config: KubeConfig) = {
    val certDataStream = config.caCertData.map(data => new ByteArrayInputStream(Base64.getDecoder.decode(data)))
    val certFileStream = config.caCertFile.map(new FileInputStream(_))

    certDataStream.orElse(certFileStream).foreach { certStream =>
      val certificateFactory = CertificateFactory.getInstance("X509")
      val certificate        = certificateFactory.generateCertificate(certStream).asInstanceOf[X509Certificate] // scalafix:ok
      defaultTrustStore.setCertificateEntry(certificate.getSubjectX500Principal.getName, certificate)
    }

    val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm)
    trustManagerFactory.init(defaultTrustStore)
    trustManagerFactory.getTrustManagers
  }

  private lazy val defaultTrustStore = {
    val securityDirectory = s"${System.getProperty("java.home")}/lib/security"

    val propertyTrustStoreFile =
      Option(System.getProperty(TrustStoreSystemProperty, "")).filter(_.nonEmpty).map(new File(_))
    val jssecacertsFile = Option(new File(s"$securityDirectory/jssecacerts")).filter(f => f.exists && f.isFile)
    val cacertsFile     = new File(s"$securityDirectory/cacerts")

    val keyStore = KeyStore.getInstance(KeyStore.getDefaultType)
    keyStore.load(
      new FileInputStream(propertyTrustStoreFile.orElse(jssecacertsFile).getOrElse(cacertsFile)),
      System.getProperty(TrustStorePasswordSystemProperty, "changeit").toCharArray
    )
    keyStore
  }
} 
Example 12
Source File: AkkaGrpcServerScala.scala    From akka-grpc   with Apache License 2.0 5 votes vote down vote up
package akka.grpc.interop

import java.io.FileInputStream
import java.nio.file.{ Files, Paths }
import java.security.cert.CertificateFactory
import java.security.spec.PKCS8EncodedKeySpec
import java.security.{ KeyFactory, KeyStore, SecureRandom }

import scala.concurrent.duration._

import akka.actor.ActorSystem
import akka.util.ByteString
import akka.http.scaladsl.Http.ServerBinding
import akka.http.scaladsl.model.{ HttpRequest, HttpResponse }
import akka.http.scaladsl.{ Http2, HttpsConnectionContext }
import akka.stream.SystemMaterializer
import io.grpc.internal.testing.TestUtils
import javax.net.ssl.{ KeyManagerFactory, SSLContext }

import scala.concurrent.{ Await, Future }


case class AkkaGrpcServerScala(serverHandlerFactory: ActorSystem => HttpRequest => Future[HttpResponse])
    extends GrpcServer[(ActorSystem, ServerBinding)] {
  override def start() = {
    implicit val sys = ActorSystem()
    implicit val mat = SystemMaterializer(sys).materializer

    val testService = serverHandlerFactory(sys)

    val bindingFuture = Http2().bindAndHandleAsync(
      testService,
      interface = "127.0.0.1",
      port = 0,
      parallelism = 256, // TODO remove once https://github.com/akka/akka-http/pull/2146 is merged
      connectionContext = serverHttpContext())

    val binding = Await.result(bindingFuture, 10.seconds)
    (sys, binding)
  }

  override def stop(binding: (ActorSystem, ServerBinding)) =
    binding match {
      case (sys, binding) =>
        sys.log.info("Exception thrown, unbinding")
        Await.result(binding.unbind(), 10.seconds)
        Await.result(sys.terminate(), 10.seconds)
    }

  private def serverHttpContext() = {
    val keyEncoded =
      new String(Files.readAllBytes(Paths.get(TestUtils.loadCert("server1.key").getAbsolutePath)), "UTF-8")
        .replace("-----BEGIN PRIVATE KEY-----\n", "")
        .replace("-----END PRIVATE KEY-----\n", "")
        .replace("\n", "")

    val decodedKey = ByteString(keyEncoded).decodeBase64.toArray

    val spec = new PKCS8EncodedKeySpec(decodedKey)

    val kf = KeyFactory.getInstance("RSA")
    val privateKey = kf.generatePrivate(spec)

    val fact = CertificateFactory.getInstance("X.509")
    val is = new FileInputStream(TestUtils.loadCert("server1.pem"))
    val cer = fact.generateCertificate(is)

    val ks = KeyStore.getInstance("PKCS12")
    ks.load(null)
    ks.setKeyEntry("private", privateKey, Array.empty, Array(cer))

    val keyManagerFactory = KeyManagerFactory.getInstance("SunX509")
    keyManagerFactory.init(ks, null)

    val context = SSLContext.getInstance("TLS")
    context.init(keyManagerFactory.getKeyManagers, null, new SecureRandom)

    new HttpsConnectionContext(context)
  }

  override def getPort(binding: (ActorSystem, ServerBinding)): Int = binding._2.localAddress.getPort
} 
Example 13
Source File: Main.scala    From akka-grpc   with Apache License 2.0 5 votes vote down vote up
package example.myapp

import java.io.InputStream
import java.security.{KeyStore, SecureRandom}
import javax.net.ssl.{KeyManagerFactory, SSLContext}

import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import akka.grpc.scaladsl.ServiceHandler
import akka.http.scaladsl.{Http2, HttpsConnectionContext}

import example.myapp.echo.EchoServiceImpl
import example.myapp.echo.grpc.EchoServiceHandler

import example.myapp.helloworld.GreeterServiceImpl
import example.myapp.helloworld.grpc.GreeterServiceHandler

object Main extends App {
  implicit val system = ActorSystem()
  implicit val mat = ActorMaterializer()

  val echoHandler = EchoServiceHandler.partial(new EchoServiceImpl)
  val greeterHandler = GreeterServiceHandler.partial(new GreeterServiceImpl)
  val serviceHandler = ServiceHandler.concatOrNotFound(echoHandler, greeterHandler)

  Http2().bindAndHandleAsync(
    serviceHandler,
    interface = "localhost",
    port = 8443,
    parallelism = 256, // Needed to allow running multiple requests concurrently, see https://github.com/akka/akka-http/issues/2145
    connectionContext = serverHttpContext())

  private def serverHttpContext() = {
    // never put passwords into code!
    val password = "abcdef".toCharArray

    val ks = KeyStore.getInstance("PKCS12")
    ks.load(Option(getClass.getClassLoader.getResourceAsStream("server.p12")).get, password)

    val keyManagerFactory = KeyManagerFactory.getInstance("SunX509")
    keyManagerFactory.init(ks, password)

    val context = SSLContext.getInstance("TLS")
    context.init(keyManagerFactory.getKeyManagers, null, new SecureRandom)

    new HttpsConnectionContext(context)
  }
} 
Example 14
Source File: package.scala    From hail   with MIT License 5 votes vote down vote up
package is.hail.services

import is.hail.utils._
import org.json4s.{DefaultFormats, Formats}
import java.io.{File, FileInputStream}
import java.security.KeyStore

import javax.net.ssl.{KeyManagerFactory, SSLContext, TrustManagerFactory}
import org.apache.log4j.{LogManager, Logger}
import org.json4s.jackson.JsonMethods

class NoSSLConfigFound(
  message: String,
  cause: Throwable
) extends Exception(message, cause) {
  def this() = this(null, null)

  def this(message: String) = this(message, null)
}

case class SSLConfig(
  outgoing_trust: String,
  outgoing_trust_store: String,
  incoming_trust: String,
  incoming_trust_store: String,
  key: String,
  cert: String,
  key_store: String)

package object tls {
  lazy val log: Logger = LogManager.getLogger("is.hail.tls")

  private[this] lazy val _getSSLConfig: SSLConfig = {
    var configFile = System.getenv("HAIL_SSL_CONFIG_FILE")
    if (configFile == null)
      configFile = "/ssl-config/ssl-config.json"
    if (!new File(configFile).isFile)
      throw new NoSSLConfigFound(s"no ssl config file found at $configFile")

    log.info(s"ssl config file found at $configFile")

    using(new FileInputStream(configFile)) { is =>
      implicit val formats: Formats = DefaultFormats
      JsonMethods.parse(is).extract[SSLConfig]
    }
  }

  lazy val getSSLContext: SSLContext = {
    val sslConfig = _getSSLConfig

    val pw = "dummypw".toCharArray

    val ks = KeyStore.getInstance("PKCS12")
    using(new FileInputStream(sslConfig.key_store)) { is =>
      ks.load(is, pw)
    }
    val kmf = KeyManagerFactory.getInstance("SunX509")
    kmf.init(ks, pw)

    val ts = KeyStore.getInstance("JKS")
    using(new FileInputStream(sslConfig.outgoing_trust_store)) { is =>
      ts.load(is, pw)
    }
    val tmf = TrustManagerFactory.getInstance("SunX509")
    tmf.init(ts)

    val ctx = SSLContext.getInstance("TLS")
    ctx.init(kmf.getKeyManagers, tmf.getTrustManagers, null)

    ctx
  }
} 
Example 15
Source File: HttpClientProvider.scala    From reactive-nakadi   with MIT License 5 votes vote down vote up
package org.zalando.react.nakadi.client.providers

import java.security.SecureRandom
import java.security.cert.X509Certificate
import javax.net.ssl.{SSLContext, TrustManager, X509TrustManager}

import akka.actor.ActorContext
import akka.http.scaladsl.Http.OutgoingConnection
import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import akka.http.scaladsl.settings.ClientConnectionSettings
import akka.http.scaladsl.{Http, HttpsConnectionContext}
import akka.stream.scaladsl.Flow

import scala.concurrent.Future
import scala.concurrent.duration._


class HttpClientProvider(actorContext: ActorContext,
                         server: String, port: Int,
                         isConnectionSSL: Boolean = false,
                         acceptAnyCertificate: Boolean = false,
                         connectionTimeout: FiniteDuration) {

  val http = Http(actorContext.system)

  private val settings = {
    ClientConnectionSettings
      .apply(actorContext.system)
      .withConnectingTimeout(connectionTimeout)
      .withIdleTimeout(Duration.Inf)
  }

  val connection: Flow[HttpRequest, HttpResponse, Future[OutgoingConnection]] = {

    isConnectionSSL match {
      case true =>
        val sslContext = if (!acceptAnyCertificate) SSLContext.getDefault else {

          val permissiveTrustManager: TrustManager = new X509TrustManager() {
            override def checkClientTrusted(chain: Array[X509Certificate], authType: String): Unit = {}
            override def checkServerTrusted(chain: Array[X509Certificate], authType: String): Unit = {}
            override def getAcceptedIssuers(): Array[X509Certificate] = Array.empty
          }

          val ctx = SSLContext.getInstance("TLS")
          ctx.init(Array.empty, Array(permissiveTrustManager), new SecureRandom())
          ctx
        }
        http.outgoingConnectionHttps(server, port, new HttpsConnectionContext(sslContext), settings = settings)
      case false =>
        http.outgoingConnection(server, port, settings = settings)
    }
  }

} 
Example 16
Source File: UsesSslContext.scala    From scala-commons   with MIT License 5 votes vote down vote up
package com.avsystem.commons
package redis

import java.io.FileInputStream
import java.security.{KeyStore, SecureRandom}

import javax.net.ssl.{KeyManagerFactory, SSLContext, SSLEngine, TrustManagerFactory}

trait UsesSslContext {
  lazy val sslContext: SSLContext = SSLContext.getInstance("TLSv1.2").setup { sslc =>
    val ks = KeyStore.getInstance("PKCS12")
    ks.load(new FileInputStream("./tls/redis.p12"), Array.empty)

    val kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm)
    kmf.init(ks, Array.empty)

    val tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm)
    tmf.init(ks)

    sslc.init(kmf.getKeyManagers, tmf.getTrustManagers, new SecureRandom)
  }
} 
Example 17
Source File: Connection.scala    From fs2-rabbit   with Apache License 2.0 5 votes vote down vote up
package dev.profunktor.fs2rabbit.algebra

import cats.data.NonEmptyList
import cats.effect.{Resource, Sync}
import cats.implicits._
import com.rabbitmq.client.{Address, ConnectionFactory, DefaultSaslConfig, SaslConfig}
import dev.profunktor.fs2rabbit.config.Fs2RabbitConfig
import dev.profunktor.fs2rabbit.effects.Log
import dev.profunktor.fs2rabbit.javaConversion._
import dev.profunktor.fs2rabbit.model.{AMQPChannel, AMQPConnection, RabbitChannel, RabbitConnection}
import javax.net.ssl.SSLContext

object ConnectionResource {
  type ConnectionResource[F[_]] = Connection[Resource[F, ?]]
  def make[F[_]: Sync: Log](
      conf: Fs2RabbitConfig,
      sslCtx: Option[SSLContext] = None,
      // Unlike SSLContext, SaslConfig is not optional because it is always set
      // by the underlying Java library, even if the user doesn't set it.
      saslConf: SaslConfig = DefaultSaslConfig.PLAIN
  ): F[Connection[Resource[F, ?]]] =
    Sync[F].delay {
      new Connection[Resource[F, ?]] {

        private[fs2rabbit] def mkConnectionFactory: F[(ConnectionFactory, NonEmptyList[Address])] =
          Sync[F].delay {
            val factory   = new ConnectionFactory()
            val firstNode = conf.nodes.head
            factory.setHost(firstNode.host)
            factory.setPort(firstNode.port)
            factory.setVirtualHost(conf.virtualHost)
            factory.setConnectionTimeout(conf.connectionTimeout)
            factory.setAutomaticRecoveryEnabled(conf.automaticRecovery)
            if (conf.ssl) {
              sslCtx.fold(factory.useSslProtocol())(factory.useSslProtocol)
            }
            factory.setSaslConfig(saslConf)
            conf.username.foreach(factory.setUsername)
            conf.password.foreach(factory.setPassword)
            val addresses = conf.nodes.map(node => new Address(node.host, node.port))
            (factory, addresses)
          }

        private[fs2rabbit] def acquireChannel(connection: AMQPConnection): F[AMQPChannel] =
          Sync[F]
            .delay(connection.value.createChannel)
            .flatTap(c => Log[F].info(s"Acquired channel: $c"))
            .map(RabbitChannel)

        private[fs2rabbit] val acquireConnection: F[AMQPConnection] =
          mkConnectionFactory.flatMap {
            case (factory, addresses) =>
              Sync[F]
                .delay(factory.newConnection(addresses.toList.asJava))
                .flatTap(c => Log[F].info(s"Acquired connection: $c"))
                .map(RabbitConnection)
          }

        override def createConnection: Resource[F, AMQPConnection] =
          Resource.make(acquireConnection) {
            case RabbitConnection(conn) =>
              Log[F].info(s"Releasing connection: $conn previously acquired.") *>
                Sync[F].delay {
                  if (conn.isOpen) conn.close()
                }
          }

        override def createChannel(connection: AMQPConnection): Resource[F, AMQPChannel] =
          Resource.make(acquireChannel(connection)) {
            case RabbitChannel(channel) =>
              Sync[F].delay {
                if (channel.isOpen) channel.close()
              }
          }
      }
    }
}

trait Connection[F[_]] {
  def createConnection: F[AMQPConnection]
  def createChannel(connection: AMQPConnection): F[AMQPChannel]
} 
Example 18
Source File: implicits.scala    From iotchain   with MIT License 5 votes vote down vote up
package jbok.network.tcp

import cats.effect.{Concurrent, ContextShift, IO, Sync}
import cats.implicits._
import fs2.Chunk
import fs2.io.tcp.Socket
import javax.net.ssl.SSLContext
import jbok.common.thread.ThreadUtil
import jbok.crypto.ssl.SSLContextHelper
import jbok.network.Message
import spinoco.fs2.crypto.io.tcp.TLSSocket

import scala.concurrent.ExecutionContext
import scala.concurrent.duration._

object implicits {
  val maxBytes: Int           = 4 * 1024 * 1024
  val timeout                 = Some(10.seconds)
  val sslEC: ExecutionContext = ThreadUtil.blockingThreadPool[IO]("jbok-tls").allocated.unsafeRunSync()._1

  implicit class TcpSocketOps[F[_]](val socket: Socket[F]) extends AnyVal {
    def readMessage(implicit F: Sync[F]): F[Message[F]] =
      socket.read(maxBytes, timeout).flatMap {
        case Some(chunk) => Message.decodeChunk(chunk)
        case None        => F.raiseError(new Exception(s"socket already closed"))
      }

    def writeMessage(message: Message[F]): F[Unit] =
      socket.write(Chunk.array(Message.encodeBytes(message).byteArray), timeout)

    def toTLSSocket(sslOpt: Option[SSLContext], client: Boolean)(implicit F: Concurrent[F], cs: ContextShift[F]): F[Socket[F]] =
      sslOpt match {
        case Some(ssl) =>
          if (client) TLSSocket.instance(socket, SSLContextHelper.clientEngine(ssl).engine, sslEC).widen[Socket[F]]
          else TLSSocket.instance(socket, SSLContextHelper.serverEngine(ssl).engine, sslEC).widen[Socket[F]]
        case None => F.pure(socket)
      }
  }
} 
Example 19
Source File: Build.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
import play.dev.filewatch.FileWatchService
import play.sbt.run.toLoggerProxy
import sbt._

import javax.net.ssl.SSLContext
import javax.net.ssl.HttpsURLConnection
import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManager
import java.security.cert.X509Certificate
import scala.annotation.tailrec
import scala.collection.mutable.ListBuffer
import scala.util.Properties

// This is an almost verbatim copy from Play's
// https://github.com/playframework/playframework/blob/master/framework/src/sbt-plugin/src/sbt-test/play-sbt-plugin/generated-keystore/project/Build.scala
// I think some parts could be trimmed but keeping the (almost) verbatim copy will ease future consolidation.
// Changes compared to Play's version:
//  - had to replace `path` with `url` in `verifyResourceContains`
object DevModeBuild {

  def jdk7WatchService = Def.setting {
    FileWatchService.jdk7(Keys.sLog.value)
  }

  def jnotifyWatchService = Def.setting {
    FileWatchService.jnotify(Keys.target.value)
  }

  // Using 30 max attempts so that we can give more chances to
  // the file watcher service. This is relevant when using the
  // default JDK watch service which does uses polling.
  val MaxAttempts = 30
  val WaitTime    = 500L

  val ConnectTimeout = 10000
  val ReadTimeout    = 10000

  private val trustAllManager = {
    val manager = new X509TrustManager() {
      def getAcceptedIssuers: Array[X509Certificate]                                = null
      def checkClientTrusted(certs: Array[X509Certificate], authType: String): Unit = {}
      def checkServerTrusted(certs: Array[X509Certificate], authType: String): Unit = {}
    }
    Array[TrustManager](manager)
  }
  @tailrec
  def verifyResourceContains(
      url: String,
      status: Int,
      assertions: Seq[String],
      attempts: Int,
      headers: (String, String)*
  ): Unit = {
    println(s"Attempt $attempts at $url")
    val messages = ListBuffer.empty[String]
    try {
      val sc = SSLContext.getInstance("SSL")
      sc.init(null, trustAllManager, null)
      HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory)

      val jnUrl = new java.net.URL(url)
      val conn  = jnUrl.openConnection().asInstanceOf[java.net.HttpURLConnection]
      conn.setConnectTimeout(ConnectTimeout)
      conn.setReadTimeout(ReadTimeout)

      headers.foreach(h => conn.setRequestProperty(h._1, h._2))

      if (status == conn.getResponseCode) messages += s"Resource at $url returned $status as expected"
      else throw new RuntimeException(s"Resource at $url returned ${conn.getResponseCode} instead of $status")

      val is = if (conn.getResponseCode >= 400) conn.getErrorStream else conn.getInputStream

      // The input stream may be null if there's no body
      val contents = if (is != null) {
        val c = IO.readStream(is)
        is.close()
        c
      } else ""
      conn.disconnect()

      assertions.foreach { assertion =>
        if (contents.contains(assertion)) messages += s"Resource at $url contained $assertion"
        else throw new RuntimeException(s"Resource at $url didn't contain '$assertion':\n$contents")
      }

      messages.foreach(println)
    } catch {
      case e: Exception =>
        println(s"Got exception: $e")
        if (attempts < MaxAttempts) {
          Thread.sleep(WaitTime)
          verifyResourceContains(url, status, assertions, attempts + 1, headers: _*)
        } else {
          messages.foreach(println)
          println(s"After $attempts attempts:")
          throw e
        }
    }
  }
} 
Example 20
Source File: ReadOptions.scala    From arangodb-spark-connector   with Apache License 2.0 5 votes vote down vote up
package com.arangodb.spark

import com.arangodb.spark.rdd.partition.ArangoDefaultPartitioner
import com.arangodb.spark.rdd.partition.ArangoPartitioner

import javax.net.ssl.SSLContext
import javax.net.ssl.SSLProtocolException
import com.arangodb.Protocol
import com.arangodb.entity.LoadBalancingStrategy

case class ReadOptions(override val database: String = "_system",
                       val collection: String = null,
                       val partitioner: ArangoPartitioner = new ArangoDefaultPartitioner(),
                       override val hosts: Option[String] = None,
                       override val user: Option[String] = None,
                       override val password: Option[String] = None,
                       override val useSsl: Option[Boolean] = None,
                       override val sslKeyStoreFile: Option[String] = None,
                       override val sslPassPhrase: Option[String] = None,
                       override val sslProtocol: Option[String] = None,
                       override val protocol: Option[Protocol] = None,
                       override val maxConnections: Option[Int] = None,
                       override val acquireHostList: Option[Boolean] = None,
                       override val acquireHostListInterval: Option[Int] = None,
                       override val loadBalancingStrategy: Option[LoadBalancingStrategy] = None) extends ArangoOptions {

  def this() = this(database = "_system")

  def database(database: String): ReadOptions = copy(database = database)

  def collection(collection: String): ReadOptions = copy(collection = collection)

  def hosts(hosts: String): ReadOptions = copy(hosts = Some(hosts))

  def user(user: String): ReadOptions = copy(user = Some(user))

  def password(password: String): ReadOptions = copy(password = Some(password))

  def useSsl(useSsl: Boolean): ReadOptions = copy(useSsl = Some(useSsl))

  def sslKeyStoreFile(sslKeyStoreFile: String): ReadOptions = copy(sslKeyStoreFile = Some(sslKeyStoreFile))

  def sslPassPhrase(sslPassPhrase: String): ReadOptions = copy(sslPassPhrase = Some(sslPassPhrase))

  def sslProtocol(sslProtocol: String): ReadOptions = copy(sslProtocol = Some(sslProtocol))

  def protocol(protocol: Protocol): ReadOptions = copy(protocol = Some(protocol))
  
  def maxConnections(maxConnections: Int): ReadOptions = copy(maxConnections = Some(maxConnections))
  
  def acquireHostList(acquireHostList: Boolean): ReadOptions = copy(acquireHostList = Some(acquireHostList))
  
  def acquireHostListInterval(acquireHostListInterval: Int): ReadOptions = copy(acquireHostListInterval = Some(acquireHostListInterval))
  
  def loadBalancingStrategy(loadBalancingStrategy: LoadBalancingStrategy): ReadOptions = copy(loadBalancingStrategy = Some(loadBalancingStrategy))

  def copy(database: String = database,
           collection: String = collection,
           partitioner: ArangoPartitioner = partitioner,
           hosts: Option[String] = hosts,
           user: Option[String] = user,
           password: Option[String] = password,
           useSsl: Option[Boolean] = useSsl,
           sslKeyStoreFile: Option[String] = sslKeyStoreFile,
           sslPassPhrase: Option[String] = sslPassPhrase,
           sslProtocol: Option[String] = sslProtocol,
           protocol: Option[Protocol] = protocol,
           maxConnections: Option[Int] = maxConnections,
           acquireHostList: Option[Boolean] = acquireHostList,
           acquireHostListInterval: Option[Int] = acquireHostListInterval,
           loadBalancingStrategy: Option[LoadBalancingStrategy] = loadBalancingStrategy): ReadOptions = {
    ReadOptions(database, collection, partitioner, hosts, user, password, useSsl, sslKeyStoreFile, sslPassPhrase, sslProtocol, protocol, maxConnections, acquireHostList, acquireHostListInterval, loadBalancingStrategy)
  }

} 
Example 21
Source File: SSLSupport.scala    From sparta   with Apache License 2.0 5 votes vote down vote up
package com.stratio.sparkta.serving.api.ssl

import java.io.FileInputStream
import java.security.{KeyStore, SecureRandom}
import javax.net.ssl.{KeyManagerFactory, SSLContext, TrustManagerFactory}

import com.stratio.sparta.serving.api.helpers.SpartaHelper.log
import com.stratio.sparta.serving.core.config.SpartaConfig
import spray.io._

import scala.util.{Failure, Success, Try}

trait SSLSupport {

  implicit def sslContext: SSLContext = {
    val context = SSLContext.getInstance("TLS")
    if(isHttpsEnabled) {
      val keyStoreResource = SpartaConfig.apiConfig.get.getString("certificate-file")
      val password = SpartaConfig.apiConfig.get.getString("certificate-password")

      val keyStore = KeyStore.getInstance("jks")
      keyStore.load(new FileInputStream(keyStoreResource), password.toCharArray)
      val keyManagerFactory = KeyManagerFactory.getInstance("SunX509")
      keyManagerFactory.init(keyStore, password.toCharArray)
      val trustManagerFactory = TrustManagerFactory.getInstance("SunX509")
      trustManagerFactory.init(keyStore)
      context.init(keyManagerFactory.getKeyManagers, trustManagerFactory.getTrustManagers, new SecureRandom)
    }
    context
  }

  implicit def sslEngineProvider: ServerSSLEngineProvider = {
    ServerSSLEngineProvider { engine =>
      engine.setEnabledCipherSuites(Array(
        "TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",
        "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", "TLS_RSA_WITH_AES_256_CBC_SHA256",
        "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384",
        "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
        "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", "TLS_RSA_WITH_AES_256_CBC_SHA",
        "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"))
      engine.setEnabledProtocols(Array( "TLSv1.2" ))
      engine
    }
  }

  def isHttpsEnabled: Boolean =
    SpartaConfig.getSprayConfig match {
      case Some(config) =>
        Try(config.getValue("ssl-encryption")) match {
          case Success(value) =>
            "on".equals(value.unwrapped())
          case Failure(e) =>
            log.error("Incorrect value in ssl-encryption option, setting https disabled", e)
            false
        }
      case None =>
        log.warn("Impossible to get spray config, setting https disabled")
        false
    }
} 
Example 22
Source File: Https.scala    From openwhisk   with Apache License 2.0 5 votes vote down vote up
package org.apache.openwhisk.common

import java.io.{FileInputStream, InputStream}
import java.security.{KeyStore, SecureRandom}
import javax.net.ssl.{KeyManagerFactory, SSLContext, TrustManagerFactory}

import akka.http.scaladsl.ConnectionContext
import akka.stream.TLSClientAuth
import com.typesafe.sslconfig.akka.AkkaSSLConfig

object Https {
  case class HttpsConfig(keystorePassword: String, keystoreFlavor: String, keystorePath: String, clientAuth: String)

  def getCertStore(password: Array[Char], flavor: String, path: String): KeyStore = {
    val cs: KeyStore = KeyStore.getInstance(flavor)
    val certStore: InputStream = new FileInputStream(path)
    cs.load(certStore, password)
    cs
  }

  def connectionContext(httpsConfig: HttpsConfig, sslConfig: Option[AkkaSSLConfig] = None) = {

    val keyFactoryType = "SunX509"
    val clientAuth = {
      if (httpsConfig.clientAuth.toBoolean)
        Some(TLSClientAuth.need)
      else
        Some(TLSClientAuth.none)
    }

    val keystorePassword = httpsConfig.keystorePassword.toCharArray

    val keyStore: KeyStore = KeyStore.getInstance(httpsConfig.keystoreFlavor)
    val keyStoreStream: InputStream = new FileInputStream(httpsConfig.keystorePath)
    keyStore.load(keyStoreStream, keystorePassword)

    val keyManagerFactory: KeyManagerFactory = KeyManagerFactory.getInstance(keyFactoryType)
    keyManagerFactory.init(keyStore, keystorePassword)

    // Currently, we are using the keystore as truststore as well, because the clients use the same keys as the
    // server for client authentication (if enabled).
    // So this code is guided by https://doc.akka.io/docs/akka-http/10.0.9/scala/http/server-side-https-support.html
    // This needs to be reworked, when we fix the keys and certificates.
    val trustManagerFactory: TrustManagerFactory = TrustManagerFactory.getInstance(keyFactoryType)
    trustManagerFactory.init(keyStore)

    val sslContext: SSLContext = SSLContext.getInstance("TLS")
    sslContext.init(keyManagerFactory.getKeyManagers, trustManagerFactory.getTrustManagers, new SecureRandom)

    ConnectionContext.https(sslContext, sslConfig, clientAuth = clientAuth)
  }
} 
Example 23
Source File: JsonRpcHttpsServer.scala    From mantis   with Apache License 2.0 5 votes vote down vote up
package io.iohk.ethereum.jsonrpc.server

import java.io.{File, FileInputStream}
import java.security.{KeyStore, SecureRandom}
import javax.net.ssl.{KeyManagerFactory, SSLContext, TrustManagerFactory}

import akka.actor.ActorSystem
import akka.http.scaladsl.model.headers.HttpOriginRange
import akka.http.scaladsl.{ConnectionContext, Http}
import akka.stream.ActorMaterializer
import io.iohk.ethereum.jsonrpc.JsonRpcController
import io.iohk.ethereum.jsonrpc.server.JsonRpcHttpsServer.HttpsSetupResult
import io.iohk.ethereum.jsonrpc.server.JsonRpcServer.JsonRpcServerConfig
import io.iohk.ethereum.utils.Logger

import scala.concurrent.ExecutionContext.Implicits.global
import scala.io.Source
import scala.util.{Failure, Success, Try}

class JsonRpcHttpsServer(val jsonRpcController: JsonRpcController, config: JsonRpcServerConfig,
                         secureRandom: SecureRandom)(implicit val actorSystem: ActorSystem)
  extends JsonRpcServer with Logger {

  def run(): Unit = {
    implicit val materializer = ActorMaterializer()

    val maybeSslContext = validateCertificateFiles(config.certificateKeyStorePath, config.certificateKeyStoreType, config.certificatePasswordFile).flatMap{
      case (keystorePath, keystoreType, passwordFile) =>
        val passwordReader = Source.fromFile(passwordFile)
        try {
          val password = passwordReader.getLines().mkString
          obtainSSLContext(keystorePath, keystoreType, password)
        } finally {
          passwordReader.close()
        }
    }

    val maybeHttpsContext = maybeSslContext.map(sslContext => ConnectionContext.https(sslContext))

    maybeHttpsContext match {
      case Right(httpsContext) =>
        Http().setDefaultServerHttpContext(httpsContext)
        val bindingResultF = Http().bindAndHandle(route, config.interface, config.port, connectionContext = httpsContext)

        bindingResultF onComplete {
          case Success(serverBinding) => log.info(s"JSON RPC HTTPS server listening on ${serverBinding.localAddress}")
          case Failure(ex) => log.error("Cannot start JSON HTTPS RPC server", ex)
        }
      case Left(error) => log.error(s"Cannot start JSON HTTPS RPC server due to: $error")
    }
  }

  
  private def validateCertificateFiles(maybeKeystorePath: Option[String],
                                       maybeKeystoreType: Option[String],
                                       maybePasswordFile: Option[String]): HttpsSetupResult[(String, String, String)] =
    (maybeKeystorePath, maybeKeystoreType, maybePasswordFile) match {
      case (Some(keystorePath), Some(keystoreType), Some(passwordFile)) =>
        val keystoreDirMissing = !new File(keystorePath).isFile
        val passwordFileMissing = !new File(passwordFile).isFile
        if(keystoreDirMissing && passwordFileMissing)
          Left("Certificate keystore path and password file configured but files are missing")
        else if(keystoreDirMissing)
          Left("Certificate keystore path configured but file is missing")
        else if(passwordFileMissing)
          Left("Certificate password file configured but file is missing")
        else
          Right((keystorePath, keystoreType, passwordFile))
      case _ =>
        Left("HTTPS requires: certificate-keystore-path, certificate-keystore-type and certificate-password-file to be configured")
    }

  override def corsAllowedOrigins: HttpOriginRange = config.corsAllowedOrigins
}

object JsonRpcHttpsServer {
  type HttpsSetupResult[T] = Either[String, T]
} 
Example 24
Source File: OutgoingManager.scala    From iotchain   with MIT License 5 votes vote down vote up
package jbok.core.peer

import java.nio.channels.AsynchronousChannelGroup

import cats.effect._
import cats.effect.implicits._
import cats.implicits._
import fs2._
import fs2.io.tcp.Socket
import javax.net.ssl.SSLContext
import jbok.common.log.Logger
import jbok.core.config.FullConfig
import jbok.core.ledger.History
import jbok.core.queue.Queue
import jbok.network.Message
import jbok.network.tcp.implicits._

import scala.concurrent.duration._
import scala.util.Random

final class OutgoingManager[F[_]](config: FullConfig, history: History[F], ssl: Option[SSLContext], val inbound: Queue[F, Peer[F], Message[F]], val store: PeerStore[F])(
    implicit F: ConcurrentEffect[F],
    cs: ContextShift[F],
    T: Timer[F],
    acg: AsynchronousChannelGroup
) extends BaseManager[F](config, history) {
  private val log = Logger[F]

  private[peer] def connectTo(peerUri: PeerUri): Resource[F, (Peer[F], Socket[F])] =
    for {
      _ <- Resource.liftF(log.i(s"connecting to ${peerUri.address}"))
      socket <- Socket
        .client[F](
          to = peerUri.address,
          reuseAddress = true,
          sendBufferSize = config.peer.bufferSize,
          receiveBufferSize = config.peer.bufferSize,
          keepAlive = true,
          noDelay = true
        )
      tlsSocket <- Resource.liftF(socket.toTLSSocket(ssl, client = true))
      peer      <- Resource.liftF(handshake(socket))
      _         <- Resource.make(connected.update(_ + (peer.uri -> (peer -> socket))).as(peer))(peer => connected.update(_ - peer.uri))
    } yield peer -> tlsSocket

  private[peer] def connect(peerUri: PeerUri): Stream[F, Unit] =
    Stream
      .resource(connectTo(peerUri))
      .flatMap {
        case (peer, socket) =>
          Stream(
            socket
              .reads(config.peer.bufferSize, None)
              .through(Message.decodePipe[F])
              .map(m => peer -> m)
              .through(inbound.sink)
              .onFinalize(log.i(s"disconnected outgoing ${peer.uri}") >> connected.update(_ - peer.uri)),
            peer.queue.dequeue.through(Message.encodePipe).through(socket.writes(None))
          ).parJoinUnbounded
      }
      .handleErrorWith(e => {
        Stream.eval(log.error(s"connect ${peerUri.address} error",e)) ++ Stream.sleep(15.seconds) ++ connect(peerUri)
      })

  val connects: Stream[F, Unit] =
    Stream.eval(store.add(config.peer.seedUris: _*)) ++
      store.subscribe
        .map(uri => connect(uri))
        .parJoin(config.peer.maxOutgoingPeers)

  val resource: Resource[F, Fiber[F, Unit]] = Resource {
    connects.compile.drain.start.map { fiber =>
      fiber -> fiber.cancel
    }
  }
} 
Example 25
Source File: IncomingManager.scala    From iotchain   with MIT License 5 votes vote down vote up
package jbok.core.peer

import java.net.InetSocketAddress
import java.nio.channels.AsynchronousChannelGroup

import cats.effect._
import cats.effect.concurrent.Deferred
import cats.effect.implicits._
import cats.implicits._
import fs2._
import fs2.io.tcp.Socket
import javax.net.ssl.SSLContext
import jbok.common.log.Logger
import jbok.core.config.FullConfig
import jbok.core.ledger.History
import jbok.core.queue.Queue
import jbok.network.Message
import jbok.network.tcp.implicits._

final class IncomingManager[F[_]](config: FullConfig, history: History[F], ssl: Option[SSLContext], val inbound: Queue[F, Peer[F], Message[F]])(
    implicit F: ConcurrentEffect[F],
    cs: ContextShift[F],
    acg: AsynchronousChannelGroup
) extends BaseManager[F](config, history) {
  private val log = Logger[F]

  val localBindAddress: Deferred[F, InetSocketAddress] = Deferred.unsafe[F, InetSocketAddress]

  val localPeerUri: F[PeerUri] = localBindAddress.get.map(addr => PeerUri.fromTcpAddr(addr))

  val peers: Stream[F, Resource[F, (Peer[F], Socket[F])]] =
    Socket
      .serverWithLocalAddress[F](
        address = config.peer.bindAddr,
        maxQueued = 10,
        reuseAddress = true,
        receiveBufferSize = config.peer.bufferSize
      )
      .flatMap {
        case Left(bound) =>
          Stream.eval_(log.i(s"IncomingManager successfully bound to address ${bound}") >> localBindAddress.complete(bound))
        case Right(res) =>
          Stream.emit {
            for {
              socket    <- res
              tlsSocket <- Resource.liftF(socket.toTLSSocket(ssl, client = false))
              peer      <- Resource.liftF(handshake(socket))
              _         <- Resource.make(connected.update(_ + (peer.uri -> (peer -> socket))).as(peer))(peer => connected.update(_ - peer.uri))
              _         <- Resource.liftF(log.i(s"accepted incoming peer ${peer.uri}"))
            } yield (peer, tlsSocket)
          }
      }

  val serve: Stream[F, Unit] =
    peers
      .map { res =>
        Stream
          .resource(res)
          .flatMap {
            case (peer, socket) =>
              Stream(
                socket
                  .reads(config.peer.bufferSize, None)
                  .through(Message.decodePipe[F])
                  .map(m => peer -> m)
                  .through(inbound.sink)
                  .onFinalize(log.i(s"disconnected incoming ${peer.uri}") >> connected.update(_ - peer.uri)),
                peer.queue.dequeue.through(Message.encodePipe[F]).through(socket.writes(None))
              ).parJoinUnbounded
          }
          .handleErrorWith(e => Stream.eval(log.w(s"handle incoming peer failure: ${e}", e)))
      }
      .parJoin(config.peer.maxIncomingPeers)

  val resource: Resource[F, PeerUri] = Resource {
    for {
      fiber   <- serve.compile.drain.start
      address <- localBindAddress.get
    } yield PeerUri.fromTcpAddr(address) -> fiber.cancel
  }
} 
Example 26
Source File: JbokClientPlatform.scala    From iotchain   with MIT License 5 votes vote down vote up
package jbok.core.api

import java.net.URI

import cats.effect._
import io.circe.Json
import javax.net.ssl.SSLContext
import jbok.network.http.HttpTransport
import jbok.network.http.client.HttpClients
import jbok.network.http.client.HttpClients.withMiddlewares
import jbok.network.rpc.RpcClient

object JbokClientPlatform {
  import jbok.codec.impl.circe._
  import io.circe.generic.auto._
  import jbok.codec.json.implicits._

  def resource[F[_]](url: String, ssl: Option[SSLContext] = None)(implicit F: ConcurrentEffect[F], cs: ContextShift[F], T: Timer[F]): Resource[F, JbokClient[F]] =
    HttpClients.okHttp[F](ssl).evalMap(withMiddlewares[F]).map { client =>
      val transport = new HttpTransport[F](url, client)
      val rpc       = RpcClient(transport)

      new JbokClient[F] {
        override def uri: URI                       = new URI(url)
        override def client: RpcClient[F, Json]     = rpc
        override def account: AccountAPI[F]         = rpc.use[AccountAPI[F]]
        override def admin: AdminAPI[F]             = rpc.use[AdminAPI[F]]
        override def block: BlockAPI[F]             = rpc.use[BlockAPI[F]]
        override def contract: ContractAPI[F]       = rpc.use[ContractAPI[F]]
        override def miner: MinerAPI[F]             = rpc.use[MinerAPI[F]]
        override def personal: PersonalAPI[F]       = rpc.use[PersonalAPI[F]]
        override def transaction: TransactionAPI[F] = rpc.use[TransactionAPI[F]]
      }
    }
} 
Example 27
Source File: SSLContextHelper.scala    From iotchain   with MIT License 5 votes vote down vote up
package jbok.crypto.ssl

import java.nio.file.Paths
import java.security.KeyStore

import cats.effect.Sync
import cats.implicits._
import javax.net.ssl.{KeyManagerFactory, SSLContext, SSLEngine, TrustManagerFactory}
import jbok.common.FileUtil
import jbok.common.log.Logger

final class ClientSSLEngine(val engine: SSLEngine) extends AnyVal

final class ServerSSLEngine(val engine: SSLEngine) extends AnyVal

object SSLContextHelper {
  def apply[F[_]](config: SSLConfig)(implicit F: Sync[F]): F[Option[SSLContext]] =
    if (!config.enabled) {
      F.pure(None)
    } else {
      Logger[F].i(s"init SSLContext from keyStore=${config.keyStorePath} trustStore=${config.trustStorePath}") >>
        FileUtil[F]
          .inputStream(Paths.get(config.keyStorePath))
          .use { keyStoreIS =>
            FileUtil[F].inputStream(Paths.get(config.trustStorePath)).use { trustStoreIS =>
              F.delay {
                val keyStore = KeyStore.getInstance("JKS")
                keyStore.load(keyStoreIS, "changeit".toCharArray)
                val keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm)
                keyManagerFactory.init(keyStore, "changeit".toCharArray)

                val trustStore = KeyStore.getInstance("JKS")
                trustStore.load(trustStoreIS, "changeit".toCharArray)
                val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm)
                trustManagerFactory.init(trustStore)

                val ctx = SSLContext.getInstance(config.protocol)
                ctx.init(keyManagerFactory.getKeyManagers, trustManagerFactory.getTrustManagers, null)
                ctx
              }
            }
          }
          .map(_.some)
    }

  def clientEngine(ctx: SSLContext): ClientSSLEngine = {
    val engine = ctx.createSSLEngine()
    engine.setUseClientMode(true)
    engine.setNeedClientAuth(true)
    new ClientSSLEngine(engine)
  }

  def serverEngine(ctx: SSLContext): ServerSSLEngine = {
    val engine = ctx.createSSLEngine()
    engine.setUseClientMode(false)
    engine.setNeedClientAuth(true)
    new ServerSSLEngine(engine)
  }
} 
Example 28
Source File: TxGenClientSpec.scala    From iotchain   with MIT License 5 votes vote down vote up
package jbok.app.txgen

import cats.effect.IO
import javax.net.ssl.SSLContext
import jbok.app.AppSpec
import jbok.app.service.HttpService
import jbok.core.api.JbokClientPlatform
import jbok.core.mining.TxGen

class TxGenClientSpec extends AppSpec {
  "TxGen via client" should {
    "generate txs via client" ignore check { objects =>
      val keyPairs    = testKeyPair :: Nil
      val httpService = objects.get[HttpService[IO]]
      val ssl         = objects.get[Option[SSLContext]]
      httpService.resource.use { server =>
        JbokClientPlatform.resource[IO](server.baseUri.toString(), ssl).use { client =>
          for {
            txGen <- TxGen[IO](keyPairs, client)
            txs   <- txGen.genValidExternalTxN(10)
            _ = println(txs)
          } yield ()
        }
      }
    }
  }
} 
Example 29
Source File: CliMain.scala    From iotchain   with MIT License 5 votes vote down vote up
package jbok.app

import java.nio.file.Paths

import cats.effect.{ExitCode, IO, IOApp}
import javax.net.ssl.SSLContext
import jbok.app.cli.Cli
import jbok.common.config.Config
import jbok.common.log.{Level, Logger}
import jbok.core.api.JbokClientPlatform
import jbok.core.config.FullConfig
import monocle.macros.syntax.lens._

import scala.concurrent.duration._

object CliMain extends IOApp {
  override def run(args: List[String]): IO[ExitCode] =
    Config[IO].read[FullConfig](Paths.get(args.head)).flatMap { config =>
      AppModule.resource[IO](config.lens(_.persist.driver).set("memory")).use { objects =>
        val config = objects.get[FullConfig]
        val ssl    = objects.get[Option[SSLContext]]
        JbokClientPlatform.resource[IO](config.service.uri, ssl).use { client =>
          val cli = new Cli[IO](client)
          for {
            _ <- Logger.setRootLevel[IO](Level.Error)
            _ <- cli.loop(5.seconds).compile.drain
          } yield ExitCode.Success
        }
      }
    }
} 
Example 30
Source File: HttpService.scala    From iotchain   with MIT License 5 votes vote down vote up
package jbok.app.service

import cats.effect.{ConcurrentEffect, Resource, Timer}
import io.circe.Json
import cats.implicits._
import fs2._
import javax.net.ssl.SSLContext
import jbok.network.http.server.middleware.{CORSMiddleware, GzipMiddleware, LoggerMiddleware, MetricsMiddleware}
import jbok.core.config.ServiceConfig
import jbok.core.api._
import jbok.crypto.ssl.SSLConfig
import jbok.network.rpc.RpcService
import jbok.network.rpc.http.Http4sRpcServer
import org.http4s.HttpRoutes
import org.http4s.implicits._
import org.http4s.server.{SSLClientAuthMode, Server}
import org.http4s.server.blaze.BlazeServerBuilder

final class HttpService[F[_]](
    config: ServiceConfig,
    sslConfig: SSLConfig,
    account: AccountAPI[F],
    admin: AdminAPI[F],
    block: BlockAPI[F],
    contract: ContractAPI[F],
    miner: MinerAPI[F],
    personal: PersonalAPI[F],
    transaction: TransactionAPI[F],
    sslOpt: Option[SSLContext]
)(implicit F: ConcurrentEffect[F], T: Timer[F]) {
  import jbok.codec.impl.circe._
  import _root_.io.circe.generic.auto._
  import jbok.codec.json.implicits._

  val rpcService: RpcService[F, Json] = {
    var service = RpcService[F, Json]
    if (config.apis.contains("account")) service = service.mount(account) else ()
    if (config.apis.contains("admin")) service = service.mount(admin) else ()
    if (config.apis.contains("block")) service = service.mount(block) else ()
    if (config.apis.contains("contract")) service = service.mount(contract) else ()
    if (config.apis.contains("miner")) service = service.mount(miner) else ()
    if (config.apis.contains("personal")) service = service.mount(personal) else ()
    if (config.apis.contains("transaction")) service = service.mount(transaction) else ()
    service
  }

  val routes: HttpRoutes[F] = Http4sRpcServer.routes(rpcService)

  private val builder: F[BlazeServerBuilder[F]] = {
    val httpApp = for {
      exportRoute <- MetricsMiddleware.exportService[F]
      withMetrics <- MetricsMiddleware[F](routes, config.enableMetrics)
      withLogger = LoggerMiddleware[F](config.logHeaders, config.logBody)((withMetrics <+> exportRoute).orNotFound)
      withCORS   = CORSMiddleware[F](withLogger, config.allowedOrigins)
      app        = GzipMiddleware[F](withCORS)
    } yield app

    val builder = httpApp.map { app =>
      BlazeServerBuilder[F]
        .withHttpApp(app)
        .withNio2(true)
        .enableHttp2(config.enableHttp2)
        .withWebSockets(config.enableWebsockets)
        .bindHttp(config.port, config.local)
    }

    val sslLClientAuthMode = sslConfig.clientAuth match {
      case "NotRequested" => SSLClientAuthMode.NotRequested
      case "Requested"    => SSLClientAuthMode.Requested
      case "Required"     => SSLClientAuthMode.Requested
      case x              => throw new IllegalArgumentException(s"SSLClientAuthMode ${x} is not supported")
    }

    sslOpt match {
      case Some(ssl) => builder.map(_.withSSLContext(ssl, sslLClientAuthMode))
      case None      => builder.map(_.enableHttp2(false))
    }
  }

  val resource: Resource[F, Server[F]] =
    Resource.liftF(builder).flatMap(_.resource)

  val stream: Stream[F, Unit] =
    if (config.enable) {
      Stream.eval(builder).flatMap(_.serve).drain
    } else {
      Stream.empty
    }
} 
Example 31
Source File: HttpClients.scala    From iotchain   with MIT License 5 votes vote down vote up
package jbok.network.http.client

import cats.effect._
import javax.net.ssl.SSLContext
import jbok.common.thread.ThreadUtil
import jbok.network.http.client.middleware.{LoggerMiddleware, MetricsMiddleware, RetryMiddleware}
import okhttp3.OkHttpClient
import org.http4s.client.Client
import org.http4s.client.blaze.BlazeClientBuilder
import org.http4s.client.okhttp.OkHttpBuilder

object HttpClients {

  def withMiddlewares[F[_]](client: Client[F])(implicit F: Concurrent[F], T: Timer[F]): F[Client[F]] =
    MetricsMiddleware(LoggerMiddleware()(RetryMiddleware()(client)))

  def okHttp[F[_]](sslContext: Option[SSLContext] = None)(implicit F: ConcurrentEffect[F], cs: ContextShift[F]): Resource[F, Client[F]] =
    ThreadUtil.blockingThreadPool[F]("jbok-okhttp-client").flatMap { blockEC =>
      val builder = sslContext match {
        case Some(ctx) => new OkHttpClient.Builder().sslSocketFactory(ctx.getSocketFactory)
        case None      => new OkHttpClient.Builder()
      }

      OkHttpBuilder[F](builder.build(), blockEC).resource
    }

  def blaze[F[_]](sslContext: Option[SSLContext] = None)(implicit F: ConcurrentEffect[F]): Resource[F, Client[F]] =
    ThreadUtil.blockingThreadPool[F]("jbok-blaze-client").flatMap { blockEC =>
      BlazeClientBuilder[F](blockEC)
        .withSslContextOption(sslContext)
        .resource
    }
}