androidretrofit2okhttppinningcertificate-pinning

OkHttp Certificate pinning Error or default behavior?


Recently, I've been testing the certificate pinning implementation provided by OkHttp using version 4.9.0 + Retrofit 2.9.0; And I've noticed that the hash check is not conjunctive but rather disjunctive.

According to the example implementation the certificate chain of publicobject.com:

Peer certificate chain:
    sha256/afwiKY3RxoMmLkuRW1l7QsPZTJPwDS2pdDROQjXw8ig=: CN=publicobject.com, OU=PositiveSSL
    sha256/klO23nT2ehFDXCfx3eHTDRESMz3asj1muO+4aIdjiuY=: CN=COMODO RSA Secure Server CA
    sha256/grX4Ta9HpZx6tSHkmCrvpApTQGo67CYDnvprLg5yRME=: CN=COMODO RSA Certification Authority
    sha256/lCppFqbkrlJ3EcVFAkeip0+44VaoJUymbnOaEUk7tEU=: CN=AddTrust External CA Root

If we change the certificate and we do so with the same provider and/or root as before, we would get something like:

Peer certificate chain:
    sha256/dklfnskvAAQFvandjfjASAFjvjvg45nbwskdvur5548=: CN=publicobject.com, OU=PositiveSSL
    sha256/klO23nT2ehFDXCfx3eHTDRESMz3asj1muO+4aIdjiuY=: CN=COMODO RSA Secure Server CA
    sha256/grX4Ta9HpZx6tSHkmCrvpApTQGo67CYDnvprLg5yRME=: CN=COMODO RSA Certification Authority
    sha256/lCppFqbkrlJ3EcVFAkeip0+44VaoJUymbnOaEUk7tEU=: CN=AddTrust External CA Root

Only the first hash changes, naturally I would assume that communications with the site should stop working since our implementation now has an incorrect hash, but that is not the case because the other three are the same as before.

Is it my error when creating a new certificate? Is this the correct behavior or an error? Is there a way to check for all hashes in the chain to be correct?


Solution

  • There's 4 certificates involved in that particular handshake, and OkHttp is happy if any of them match one of your signatures.

    This means you can survive either of these operational events:

    But if you change certificate authorities and you get a new public key, clients won't connect until you update their pins.