I am using Okhttp + Retrofit for networking in my SDK. I have a requirement to implement Certificate pinning but not enforce it. We just need to get the failure reports for pinning failure and would like the request to go through for now during the monitoring period.
TrustKit is another Certificate pinning library which provides this option to set enforce = false. With this, the request itself wouldn't fail but we can get the failure reports.
I do not see a way to achieve similar behavior using the Okhttp CertificatePinner. OkHttp would always fail the request with an exception if the Certificate pinning fails.
Do you have any suggestions on how I can achieve this behavior using the existing functionality?
Would have been easier if we could extend CertificatePinner class and override check()?
Thanks in advance.
Derived somewhat from you own answer on the issue tracker
package okhttp3
import javax.net.ssl.SSLPeerUnverifiedException
fun main() {
class LoggingCertificatePinnerInterceptor(val certificatePinner: CertificatePinner) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val host = chain.request().url.host
val certs = chain.connection()
?.handshake()?.peerCertificates.orEmpty()
try {
certificatePinner.check(host, certs)
} catch (e: SSLPeerUnverifiedException) {
e.printStackTrace()
}
return chain.proceed(chain.request())
}
}
val certificatePinner = CertificatePinner.Builder()
.add("graph.facebook.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
.build()
val client = OkHttpClient.Builder()
.addNetworkInterceptor(LoggingCertificatePinnerInterceptor(certificatePinner))
.build()
val request = Request.Builder()
.url("https://graph.facebook.com/robots.txt")
.build()
val response = client.newCall(request)
.execute()
println(response.code)
}
javax.net.ssl.SSLPeerUnverifiedException: Certificate pinning failure!
Peer certificate chain:
sha256/KVFbweB8Ag9f08MZWU7m7cG83tpv8Ml39JpOHU3ESMg=: CN=*.facebook.com, O="Facebook, Inc.", L=Menlo Park, ST=California, C=US
sha256/k2v657xBsOVe1PQRwOsHsw3bsGT2VzIqz5K+59sNQws=: CN=DigiCert SHA2 High Assurance Server CA, OU=www.digicert.com, O=DigiCert Inc, C=US
sha256/WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=: CN=DigiCert High Assurance EV Root CA, OU=www.digicert.com, O=DigiCert Inc, C=US
Pinned certificates for graph.facebook.com:
sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
at okhttp3.CertificatePinner.check$okhttp(CertificatePinner.kt:199)
at okhttp3.CertificatePinner.check(CertificatePinner.kt:149)
at okhttp3.XxXKt$main$LoggingCertificatePinnerInterceptor.intercept(XxX.kt:13)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:34)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:82)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100)
at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:197)
at okhttp3.internal.connection.RealCall.execute(RealCall.kt:148)
at okhttp3.XxXKt.main(XxX.kt:32)
at okhttp3.XxXKt.main(XxX.kt)
200
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.