Skip to content
This repository was archived by the owner on Apr 5, 2023. It is now read-only.

Conversation

@harika-konagala
Copy link

@harika-konagala harika-konagala commented Jul 8, 2019

Summary

  • MOB-828

  • Implementation Details:
    Optimizely’s Client class in com.optimizely.ab.android.shared package is used to make all it's Http connections. This class is primarily used to create a DatafileClient and an EventClient for downloading the datafile and posting client events respectively.
    To do so, it interacts with the following hosts -

    1. datafile download - cdn.optimizely.com
    2. event dispatch - logx.optimizely.com

The Client’s constructor before certificate pinning:

public Client(@NonNull OptlyStorage optlyStorage, @NonNull Logger logger) {
   this(optlyStorage, logger);
}

The Client’s constructors after certificate pinning:

public Client(@NonNull OptlyStorage optlyStorage, @NonNull Logger logger) {
   this(optlyStorage, logger, /* sslSocketFactory = */ null);
}

public Client(@NonNull OptlyStorage optlyStorage, @NonNull Logger logger, SSLSocketFactory sslSocketFactory) {
   this.optlyStorage = optlyStorage;
   this.logger = logger;
   this.mSslSocketFactory = sslSocketFactory;
}

The reason to take this approach is to avoid a breaking change, this implementation overloads the constructor with an optional SSLSocketFactory to make secure HttpsURLConnection with pinning in place. Now, Whenever the Client is instantiated, we need to pass SSLSocketFactory as the third parameter. In all other cases, it would default to null and work as expected.

Secondly, the approach followed to implement pinning is based off pinning your certificates through a custom TrustManager and SSLSocketFactory. Here is a better explanation for how PinnedSSLSocketFactory class works: https://developer.android.com/training/articles/security-ssl

Overall, the Key goals achieved here are - certificate validation from the trusted server, hostname verification.

Test plan

Charles -
The goal here is to make sure that the server is our trusted server, and not a third party impersonating our server. To do so, here are the steps to follow:

  1. Open Charles
  2. Enable SSL Proxying
  3. Install Charles root certificate on the test device giving it permission to act as the man-in-the- middle between our app and Optimizely Server
  4. Run the test-app on test device
  5. Navigate through the app
  6. Observe Charles Logs to notice that the connection has failed because the client was unable to recognize the CA

Screen Shot 2019-07-07 at 7 08 36 PM

Screen Shot 2019-07-07 at 6 58 53 PM

  1. Open Android studio and check the Logcat to notice the classic javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

Screen Shot 2019-07-07 at 7 10 11 PM

Screen Shot 2019-07-07 at 7 11 11 PM

In this case, the SSLHandshakeException occurs because we have a CA that isn't trusted by the system. To be more specific, it is because charles certificate isn't yet trusted by our app.
Fortunately, we can teach HttpsURLConnection to trust a specific set of CAs. And that is exactly what the above implementation does - making sure the connection only uses our CAs for certificate validation. And this test should prove that our certificate pinning is working as expected.

If we add the Charles certificate to the list of our trusted CAs, ideally the connection should be established and Charles should be able to view the contents.

Screen Shot 2019-07-09 at 4 05 58 PM

Screen Shot 2019-07-09 at 4 06 06 PM

Issues

  • While hardcoding the host type is not an ideal solution, there wasn't much value in making it dynamic since we are already aware of Optimizely's hosts and any change to that will require a version update.

@ujjawalgarg ujjawalgarg merged commit e6e3f79 into master Jul 10, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants