Demonstrate how to connect to a web server over HTTPS where that server requires that the client present a certificate to prove who (s)he is. Unlike with the HTTPS request with authentication task, it is not acceptable to perform the authentication by a username/password or a set cookie.

This task is in general useful for use with webservice clients as it offers a high level of assurance that the client is an acceptable counterparty for the server. For example, Amazon Web Services uses this style of authentication.

import java.io.FileInputStream
import java.net.URL
import java.security.KeyStore
 
import javax.net.ssl.{HttpsURLConnection, KeyManagerFactory, SSLContext}
 
import scala.io.BufferedSource
 
object ClientAuthenticated extends App {
 
  val con: HttpsURLConnection =
    new URL("https://somehost.com").openConnection().asInstanceOf[HttpsURLConnection]
 
  def getSSLContext(p12Path: String, password: String): SSLContext = {
    val ks = KeyStore.getInstance("pkcs12")
    val pwd = password.toCharArray
    ks.load(new FileInputStream(p12Path), pwd)
    val kmf = KeyManagerFactory.getInstance("PKIX")
    kmf.init(ks, pwd)
    val sc = SSLContext.getInstance("TLS")
    sc.init(kmf.getKeyManagers, null, null)
    sc
  }
 
  // The .p12 file contains the client certificate and private key
  HttpsURLConnection.setDefaultSSLSocketFactory(getSSLContext("whatever.p12", "password").getSocketFactory)
  new BufferedSource(con.getInputStream).getLines.foreach(println(_))
 
}