From 2bd2eb33c05b4b580689bbe62048e7393086b2ec Mon Sep 17 00:00:00 2001 From: Chad Brubaker Date: Tue, 10 Nov 2015 10:52:27 -0800 Subject: [PATCH] Dedupe trust anchors When getting trust anchors we need to dedup them based on the certificate to avoid having multiple trust anchors with the same cert but different pin override behavior. If there are multiple trust anchors with the same cert, the trust anchor which overrides pins wins. Change-Id: Ida31f2551f56997418b8b091bb2598c5593cb069 --- .../net/config/NetworkSecurityConfig.java | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) 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; } }