Search code examples
scalasslsslhandshakeexception

Scala: How to ignore 'SSLHandshakeException'


With such code:

val html = Source.fromURL("https://scans.io/json")

Getting exception:

Exception in thread "main" javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1886)
...

I can find how to fix in Java but have no idea - how to fix it in Scala?


Solution

  • You can achieve this by configuring a SSLContext.

    Here is a working code

    import javax.net.ssl._
    import java.security.cert.X509Certificate
    import scala.io.Source
    
    // Bypasses both client and server validation.
    object TrustAll extends X509TrustManager {
      val getAcceptedIssuers = null
    
      override def checkClientTrusted(x509Certificates: Array[X509Certificate], s: String) = {}
    
      override def checkServerTrusted(x509Certificates: Array[X509Certificate], s: String) = {}
    }
    
    // Verifies all host names by simply returning true.
    object VerifiesAllHostNames extends HostnameVerifier {
      def verify(s: String, sslSession: SSLSession) = true
    }
    
    // Main class
    object Test extends App {
      // SSL Context initialization and configuration
      val sslContext = SSLContext.getInstance("SSL")
      sslContext.init(null, Array(TrustAll), new java.security.SecureRandom())
      HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory)
      HttpsURLConnection.setDefaultHostnameVerifier(VerifiesAllHostNames)
      
      // Actual call
      val html = Source.fromURL("https://scans.io/json")
      println(html.mkString)
    }
    

    How it works

    Source.fromURL uses java.net.HttpURLConnection behind the scene. So this code simply works because TrustAll bypasses checkClientTrusted and checkServerTrusted methods.