For more information https://blog.jeroenhd.nl/article/android-7-nougat-and-certificate-authorities
Ran into this issue as well while trying to check for privacy implications of an app. The blog post and docs linked above does explain what happened, but not how. Source code references follows based on nougat-mr2.3.
The change was made in commit aosp-mirror/platform_frameworks_base@32d2a10, see frameworks/base:core/java/android/security/net/config/NetworkSecurityConfig.java. After that change, only the system root store (
/etc/security/cacerts) is considered.
NetworkSecurityConfig.getDefaultBuilderis used in XmlConfigSource.java when parsing the configuration file, if the option is not found in the APK, then it uses that default (which only includes the system root).
XmlConfigSource (and the fallback to getDefaultBuilder) is used in NetworkSecurityConfig, which is used all over the place. And unlike permissions, this configuration does not seem cached in /data/system/.
Editing each APK after installation and upgrades seem fragile...
So let's turn to the alternative since I have root, adding the certificate to the root store in
/etc/security/cacerts/. Certificates here are stored based on the hash of the Subject field plus an index number (increasing from 0; in case the same certificate is issues with multiple hash algorithms, e.g. SHA-1 and SHA-256).
$ openssl x509 -noout -subject_hash_old -in ~/.mitmproxy/mitmproxy-ca-cert.pem c8750f0d
Now you need to copy your PEM-encoded CA file to the system partition, like:
$ adb root $ adb push ~/.mitmproxy/mitmproxy-ca-cert.pem /etc/security/cacerts/c8750f0d.0 $ adb shell chmod 644 /etc/security/cacerts/c8750f0d.0
In my case, my
/systemwas readonly and I could not write it. So as workaround, I cloned the cacerts directory from system to userdata, added the cert and bind-mounted it over the system directory.
ca=~/.mitmproxy/mitmproxy-ca-cert.pem hash=$(openssl x509 -noout -subject_hash_old -in $ca) adb root adb shell cp -a /etc/security/cacerts /data/ adb push $ca /data/cacerts/$hash.0 adb shell chmod 644 /data/cacerts/$hash.0 adb shell mount --bind /data/cacerts /etc/security/cacerts adb unroot # optional: restart adbd as normal user
Restarted the app, and it works! No more "Trust anchor for certification path not found." errors!
Note: this needs to be done once every time you restart the device and want to perform a mitm.