diff --git a/core/java/android/security/net/config/NetworkSecurityConfig.java b/core/java/android/security/net/config/NetworkSecurityConfig.java index 8906f9b670d4b..9eab80ca07713 100644 --- a/core/java/android/security/net/config/NetworkSecurityConfig.java +++ b/core/java/android/security/net/config/NetworkSecurityConfig.java @@ -16,11 +16,14 @@ package android.security.net.config; +import android.util.ArrayMap; import android.util.ArraySet; +import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Set; import javax.net.ssl.X509TrustManager; @@ -57,12 +60,24 @@ public final class NetworkSecurityConfig { if (mAnchors != null) { return mAnchors; } - Set anchors = new ArraySet(); + // Merge trust anchors based on the X509Certificate. + // If we see the same certificate in two TrustAnchors, one with overridesPins and one + // without, the one with overridesPins wins. + Map anchorMap = new ArrayMap<>(); for (CertificatesEntryRef ref : mCertificatesEntryRefs) { - anchors.addAll(ref.getTrustAnchors()); + Set anchors = ref.getTrustAnchors(); + for (TrustAnchor anchor : anchors) { + if (anchor.overridesPins) { + anchorMap.put(anchor.certificate, anchor); + } else if (!anchorMap.containsKey(anchor.certificate)) { + anchorMap.put(anchor.certificate, anchor); + } + } } + ArraySet anchors = new ArraySet(anchorMap.size()); + anchors.addAll(anchorMap.values()); mAnchors = anchors; - return anchors; + return mAnchors; } }