Network Security Configuration

Problem: SSL Certificate Errors

  • SSLHandshakeException and kin
    • Unrecognized certificate
    • Self-signed certificate
  • Non-Solution: Accept-all TrustManager
    • Readily enables interception attacks
    • Gets you banned from the Play Store

Enter Network Security Configuration

  • Create XML resource with "use this certificate" rule
  • Add android:networkSecurityConfig on <application> to manifest
  • It Just Works™

OK, There's One Problem

  • Network security configuration debuted with Android 7.0
  • Rules will be ignored on older versions of Android

I Can Haz Backport?

TrustKit-Android

  • https://github.com/datatheorem/TrustKit-Android
  • Limited subset of rules
  • Requires manual integration with HTTP client API
    • HttpURLConnection
    • OkHttp3
  • Cleanroom implementation from spec
  • Works to API Level 17

I Can Haz Backport?

CWAC-NetSecurity

  • https://github.com/commonsguy/cwac-netsecurity
  • Supports most of the rules
  • Requires manual integration with HTTP client API
    • HttpURLConnection
    • OkHttp3
  • True backport, based on official AOSP code
  • Works to API Level 17

Using CWAC-NetSecurity

  • Set up standard network security configuration
  • Add a <meta-data> element your manifest
  • Add library to build.gradle
  • new TrustManagerBuilder().withManifestConfig(ctxt)
  • Tie the TrustManagerBuilder into your HTTP client

Configuration XML

  • <domain-config>: rules for a particular domain/set of sub-domains
  • <base-config>: baseline rules, if any
  • <debug-overrides>: rules only for debuggable builds

Debug-Only Behavior

  • Put rules in <debug-overrides>
  • Example: self-signed certificate only for debug builds

Self-Signed Certificate

  • Create a raw resource with CRT or PEM file
  • Add <certificates src="@raw/..."> without anything else to configuration
  • Skipping <certificates src="system"> blocks all default CAs

Limiting Possible Authorities

  • Create a raw resource with the root certificate of that authority
  • Add <certificates src="@raw/..."> without anything else to configuration
  • Skipping <certificates src="system"> blocks all default CAs
  • IOW, same as self-signed, just with CA's root certificate

Banning Cleartext Traffic

  • Native 7.0: cleartextTrafficPermitted="false" on a configuration element to ban for that scope
  • Native 6.0: android:usesCleartextTraffic="false" on <application>
  • CWAC-NetSecurity: native 7.0 approach works for OkHttp3 integration

Pinning Certificates

  • Create a <pin-set> element in configuration
  • Add 1+ child <pin> with certificate hash via openssl x509 -in server.crt -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64
  • Decide on expiration date, if any (fails open after that date)

CWAC-NetSecurity: Flexible Configurations

Or, Testing Manifest-Declared Stuff is Painful

  • Use withConfig(), supplying a Context and the XML resource ID
  • Benefits
    • Can choose different resources at runtime based on situation
    • Always uses the backport, for consistency across OS versions

CWAC-NetSecurity: Certificate Memorization

Basically, On-The-Fly Soft Pinning

  • If enabled, default is "trust on first use" (TOFU)
  • If certificate received does not match certificate we have seen before, custom exception
  • You prompt user for what to do
    • Yes, it's OK — IT warned me about this
    • Um, let's use it for now, but bug me again later
    • Abandon ship! Abandon ship!

Questions?