javaregexsslexception

Best way to extract common name from SSLPeerUnverifiedException?


I got the following exception on Fabric:

Non-fatal Exception: javax.net.ssl.SSLPeerUnverifiedException: Hostname assets.domain.com not verified:
    certificate: sha256/6NEXAaHJ2CAMKUOkWhMCwH9biv2QtAFsYMl0WqkocgM=
    DN: CN=apc.aptilo.com,OU=Domain Control Validated - RapidSSL(R),OU=See www.rapidssl.com/resources/cps (c)13,OU=GT19785026,2.5.4.5=#13204456444273427335456d62337a6151706e6e6d356744615556354b6a63696c44
    subjectAltNames: [apc.aptilo.com]
       at okhttp3.internal.connection.RealConnection.connectTls(SourceFile:250)
       at okhttp3.internal.connection.RealConnection.establishProtocol(SourceFile:198)
       at okhttp3.internal.connection.RealConnection.buildConnection(SourceFile:174)
       at okhttp3.internal.connection.RealConnection.connect(SourceFile:114)
       at okhttp3.internal.connection.StreamAllocation.findConnection(SourceFile:193)
       at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(SourceFile:129)
       at okhttp3.internal.connection.StreamAllocation.newStream(SourceFile:98)
       at okhttp3.internal.connection.ConnectInterceptor.intercept(SourceFile:42)
       at okhttp3.internal.http.RealInterceptorChain.proceed(SourceFile:92)
       at okhttp3.internal.http.RealInterceptorChain.proceed(SourceFile:67)
       at okhttp3.internal.cache.CacheInterceptor.intercept(SourceFile:109)
       at okhttp3.internal.http.RealInterceptorChain.proceed(SourceFile:92)
       at okhttp3.internal.http.RealInterceptorChain.proceed(SourceFile:67)
       at okhttp3.internal.http.BridgeInterceptor.intercept(SourceFile:93)
       at okhttp3.internal.http.RealInterceptorChain.proceed(SourceFile:92)
       at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(SourceFile:124)
       at okhttp3.internal.http.RealInterceptorChain.proceed(SourceFile:92)
       at okhttp3.internal.http.RealInterceptorChain.proceed(SourceFile:67)
       at okhttp3.RealCall.getResponseWithInterceptorChain(SourceFile:170)
       at okhttp3.RealCall.access$100(SourceFile:33)
       at okhttp3.RealCall$AsyncCall.execute(SourceFile:120)
       at okhttp3.internal.NamedRunnable.run(SourceFile:32)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
       at java.lang.Thread.run(Thread.java:818)

And together with the security team we've realized that this is probably a case where the user opened our app connected to some hotel Wi-Fi and was branded with those pesky login pages. Only 2 users seem to be affected so far and we have many more users so it's not like this is a real man-in-the-middle attack.

As such, I want to validate the common name on the exception. If it matches our host, assets.domain.com, than it's a potential attack and I want to log the occurrence. If the CN is different, than I just want to suppress the error.

What are my options? I can only think of parsing the exception cause string and with a regex extract the CN=value part. But is there a better less error-prone solution?

tl;dr;

I want to extract the CN value from the SSLPeerUnverifiedException and compare it our valid hostname. What's the best way to achieve this?


Solution

  • With the limited sample you provide, it's something like this

    "(?s)SSLPeerUnverifiedException:.*?(?<!\\S)CN=([^\\s,]+)(?=,)"

    where capture group 1 contains the CN value.

    Output:

     **  Grp 0 -  ( pos 35 , len 165 ) 
    SSLPeerUnverifiedException: Hostname assets.domain.com not verified:
        certificate: sha256/6NEXAaHJ2CAMKUOkWhMCwH9biv2QtAFsYMl0WqkocgM=
        DN: CN=apc.aptilo.com  
     **  Grp 1 -  ( pos 186 , len 14 ) 
    apc.aptilo.com