Hi,

I have written a small HTTPS test server and client and now I try to 
disable hostname verification. Here is the code:

object HttpsServer extends App {

  implicit val system = ActorSystem("system")
  implicit val mat = ActorMaterializer()
  implicit val ec = system.dispatcher

  val serverContext: HttpsContext = {
    val password = "123456789".toCharArray
    val context = SSLContext.getInstance("TLS")
    val ks = KeyStore.getInstance("PKCS12")
    val is = getClass.getResource("mykeystore.pkcs12").openStream()
    ks.load(is, password)
    val keyManagerFactory = KeyManagerFactory.getInstance("SunX509")
    keyManagerFactory.init(ks, password)
    context.init(keyManagerFactory.getKeyManagers, null, new SecureRandom)
    // start up the web server
    HttpsContext(context)
  }

  // credentials used to authenticate users
  val credentials = Map("test" -> ("test", Set("user")))

  // authenticator used to authenticate users, uses credentials
  def authenticator[T](cred: Credentials) : Option[Set[String]] =
    cred match {
      case cred@Credentials.Provided(name) =>
        credentials.get(name).flatMap {
          case (pass, roles) =>
            if(cred.verify(pass))
              Some(roles)
            else
              None
        }
      case Credentials.Missing =>
        None
    }

  val route = authenticateBasic("HTTP test server", authenticator) { roles ⇒
    get {
      path ("test.txt") {
        complete ("Hello, World")
      }
    }
  }

  val binding = Http(system).bindAndHandle(
    interface = "0.0.0.0",
    port = 6443,
    handler = route,
    httpsContext = Some(serverContext)
  )

  binding onFailure {
    case ex: Exception => println("Failed to bind to port 8888, reason {}", ex)
  }
}

object ConnectionLevelHttpsClient extends App {

  val config = ConfigFactory.parseURL(getClass.getResource("httpsclient.conf"))

  implicit val system = ActorSystem("ConnectionLevelHttpsClient", config)
  implicit val materializer = ActorMaterializer()
  implicit val ec = system.dispatcher

  val auth = Authorization(BasicHttpCredentials("test", "test"))

  private val trustfulSslContext: SSLContext = {

    object NoCheckX509TrustManager extends X509TrustManager {
      override def checkClientTrusted(chain: Array[X509Certificate], authType: 
String) = ()
      override def checkServerTrusted(chain: Array[X509Certificate], authType: 
String) = ()
      override def getAcceptedIssuers = Array[X509Certificate]()
    }

    val context = SSLContext.getInstance("TLS")
    context.init(Array[KeyManager](), Array(NoCheckX509TrustManager), null)
    context
  }

  val trustfulClientContext: HttpsContext =
    HttpsContext(trustfulSslContext)

  val allHostsValid = new HostnameVerifier() {
    override def verify(s: String, sslSession: SSLSession): Boolean = true
  }
  HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid)


  val connectionFlow: Flow[HttpRequest, HttpResponse, 
Future[Http.OutgoingConnection]] =
    Http().outgoingConnectionTls("localhost", 6443, httpsContext = 
Some(trustfulClientContext))
  val responseFuture: Future[String] =
    Source.single(HttpRequest(uri = "/test.txt", headers = List(auth)))
      .via(connectionFlow)
      .runWith(Sink.head).flatMap { response =>
      if (response.status == StatusCodes.OK) {
        Unmarshal(response).to[String]
      } else {
        Future.successful("Error: " + response.status)
      }
    }
  responseFuture.onSuccess {
    case result => println(result)
  }
  responseFuture.onFailure {
    case ex => ex.printStackTrace()
  }
}

The whole project is here: https://github.com/mthaler/akka-http-test

The server is using a self-signed certificate and the client ignores the 
certificate. The code works, but when I change 

Http().outgoingConnectionTls("localhost", 6443, httpsContext = 
Some(trustfulClientContext))

to 

Http().outgoingConnectionTls("127.0.0.1", 6443, httpsContext = 
Some(trustfulClientContext))


I get an error:

akka.stream.ConnectionException: Hostname verification failed! Expected session 
to be for 127.0.0.1


I tried to disable hostname verification by setting an all-trusing hostname 
verifier and also by including

akka.ssl-config.ssl.loose.acceptAnyCertificate=true
akka.ssl-config.loose.disableHostnameVerification = true 
akka.ssl-config.ssl.loose.disableHostnameVerification = true


ssl-config.ssl.loose.acceptAnyCertificate=true
ssl-config.loose.disableHostnameVerification = true
ssl-config.ssl.loose.disableHostnameVerification = true


in httpsclient.conf. I also tried to remove my custom HttpsContext. But nothing 
seems to work. I am using Java 7 and akka-http 2.0.3.
How can I disable hostname verification?

(I know it is not good practice to trust all certificates and disable hostname 
verification.)

Best regards,
Michael


-- 
>>>>>>>>>>      Read the docs: http://akka.io/docs/
>>>>>>>>>>      Check the FAQ: 
>>>>>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>>      Search the archives: https://groups.google.com/group/akka-user
--- 
You received this message because you are subscribed to the Google Groups "Akka 
User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to akka-user+unsubscr...@googlegroups.com.
To post to this group, send email to akka-user@googlegroups.com.
Visit this group at https://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.

Reply via email to