bunq / sdk_java

Java SDK for bunq API
MIT License
49 stars 24 forks source link

Certificate pinning issue after bunq certificate renewal #115

Closed erwindeg closed 5 years ago

erwindeg commented 5 years ago

Steps to reproduce:

  1. Create a BunqContext with the Java SDK

What should happen:

  1. Session should be successfully created and payments should succeed

What happens:

  1. Creation fails with com.bunq.sdk.exception.UncaughtExceptionError: Uncaught exception "Certificate pinning failure!"

SDK version and environment

Extra info:

It looks like your certificate for https://public-api.sandbox.bunq.com/ was renewed last night and now the hardcoded pinned key in the SDK doesn't match the key of the new certificate

OGKevin commented 5 years ago

waw 🤦‍♂️ 👏, lets hope that they will be more careful when doing this on prod. This prob means that all SDK's are broken. There is a way you can fix this yourself however, anyone can update the hardcoded cert. I forgot the command however, it was in my notes back in the day. @kojoru If esan is still there, you can ask him if he remembers.

erwindeg commented 5 years ago

This should be the new value: sha256/9Y+oZve6H+r17Kdn+lN5sT0ijgxLyDGIuQtUwLupawA=

OGKevin commented 5 years ago

This should be the new value: sha256/9Y+oZve6H+r17Kdn+lN5sT0ijgxLyDGIuQtUwLupawA=

A nice, create a pull request I would say 😊 Also, it would be a good idea to add a comment in the code in https://github.com/bunq/sdk_java/blob/f3818e3380b472cafd1dbe69bf45a78434f54c84/src/main/java/com/bunq/sdk/context/ApiEnvironmentType.java on the command to run to update it 😊

erwindeg commented 5 years ago

Yes, I just did :)

mwlynch commented 5 years ago

FYI: This is how we got the new value. Run this and grab the new key from the log output.

        String hostname = "public-api.sandbox.bunq.com";

        CertificatePinner certificatePinner = new CertificatePinner.Builder()
                .add(hostname, "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
                .build();

        OkHttpClient client = new OkHttpClient.Builder()
                .certificatePinner(certificatePinner)
                .build();

        Request request = new Request.Builder()
                .url("https://" + hostname)
                .build();
        client.newCall(request).execute();
OGKevin commented 5 years ago

hmm, I used to use the openssl command to get this. That was the command I was referring tho. Interesting method however :P

mwlynch commented 5 years ago

There, I figured it out :-P

openssl s_client -connect sandbox.bunq.com:443 -showcerts < /dev/null 2> /dev/null | openssl x509 -pubkey -noout | openssl enc -base64 -d | openssl dgst -sha256 -binary | openssl enc -base64

(and yes, this is considerably more classy than grabbing it from okhttp's error output...)