Support TrustedCertificateStore.findAllIssuers
Change-Id: I176ec42c9907e50ee218e4fb352b530ca797be46
diff --git a/core/java/android/security/net/config/CertificateSource.java b/core/java/android/security/net/config/CertificateSource.java
index 7e3601e..f3272e4 100644
--- a/core/java/android/security/net/config/CertificateSource.java
+++ b/core/java/android/security/net/config/CertificateSource.java
@@ -16,12 +16,13 @@
package android.security.net.config;
-import java.util.Set;
import java.security.cert.X509Certificate;
+import java.util.Set;
/** @hide */
public interface CertificateSource {
Set<X509Certificate> getCertificates();
X509Certificate findBySubjectAndPublicKey(X509Certificate cert);
X509Certificate findByIssuerAndSignature(X509Certificate cert);
+ Set<X509Certificate> findAllByIssuerAndSignature(X509Certificate cert);
}
diff --git a/core/java/android/security/net/config/CertificatesEntryRef.java b/core/java/android/security/net/config/CertificatesEntryRef.java
index ff728ef..742d430 100644
--- a/core/java/android/security/net/config/CertificatesEntryRef.java
+++ b/core/java/android/security/net/config/CertificatesEntryRef.java
@@ -17,8 +17,8 @@
package android.security.net.config;
import android.util.ArraySet;
-import java.util.Set;
import java.security.cert.X509Certificate;
+import java.util.Set;
/** @hide */
public final class CertificatesEntryRef {
@@ -60,4 +60,8 @@
return new TrustAnchor(foundCert, mOverridesPins);
}
+
+ public Set<X509Certificate> findAllCertificatesByIssuerAndSignature(X509Certificate cert) {
+ return mSource.findAllByIssuerAndSignature(cert);
+ }
}
diff --git a/core/java/android/security/net/config/DirectoryCertificateSource.java b/core/java/android/security/net/config/DirectoryCertificateSource.java
index bf29efa..b2c068c 100644
--- a/core/java/android/security/net/config/DirectoryCertificateSource.java
+++ b/core/java/android/security/net/config/DirectoryCertificateSource.java
@@ -29,6 +29,7 @@
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
+import java.util.Collections;
import java.util.Set;
import libcore.io.IoUtils;
@@ -110,10 +111,50 @@
});
}
+ @Override
+ public Set<X509Certificate> findAllByIssuerAndSignature(final X509Certificate cert) {
+ return findCerts(cert.getIssuerX500Principal(), new CertSelector() {
+ @Override
+ public boolean match(X509Certificate ca) {
+ try {
+ cert.verify(ca.getPublicKey());
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+ });
+ }
+
private static interface CertSelector {
boolean match(X509Certificate cert);
}
+ private Set<X509Certificate> findCerts(X500Principal subj, CertSelector selector) {
+ String hash = getHash(subj);
+ Set<X509Certificate> certs = null;
+ for (int index = 0; index >= 0; index++) {
+ String fileName = hash + "." + index;
+ if (!new File(mDir, fileName).exists()) {
+ break;
+ }
+ if (isCertMarkedAsRemoved(fileName)) {
+ continue;
+ }
+ X509Certificate cert = readCertificate(fileName);
+ if (!subj.equals(cert.getSubjectX500Principal())) {
+ continue;
+ }
+ if (selector.match(cert)) {
+ if (certs == null) {
+ certs = new ArraySet<X509Certificate>();
+ }
+ certs.add(cert);
+ }
+ }
+ return certs != null ? certs : Collections.<X509Certificate>emptySet();
+ }
+
private X509Certificate findCert(X500Principal subj, CertSelector selector) {
String hash = getHash(subj);
for (int index = 0; index >= 0; index++) {
diff --git a/core/java/android/security/net/config/KeyStoreCertificateSource.java b/core/java/android/security/net/config/KeyStoreCertificateSource.java
index b6105cd..ba5dd83 100644
--- a/core/java/android/security/net/config/KeyStoreCertificateSource.java
+++ b/core/java/android/security/net/config/KeyStoreCertificateSource.java
@@ -21,6 +21,7 @@
import java.security.KeyStoreException;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
+import java.util.Collections;
import java.util.Enumeration;
import java.util.Set;
@@ -90,4 +91,18 @@
}
return anchor.getTrustedCert();
}
+
+ @Override
+ public Set<X509Certificate> findAllByIssuerAndSignature(X509Certificate cert) {
+ ensureInitialized();
+ Set<java.security.cert.TrustAnchor> anchors = mIndex.findAllByIssuerAndSignature(cert);
+ if (anchors.isEmpty()) {
+ return Collections.<X509Certificate>emptySet();
+ }
+ Set<X509Certificate> certs = new ArraySet<X509Certificate>(anchors.size());
+ for (java.security.cert.TrustAnchor anchor : anchors) {
+ certs.add(anchor.getTrustedCert());
+ }
+ return certs;
+ }
}
diff --git a/core/java/android/security/net/config/NetworkSecurityConfig.java b/core/java/android/security/net/config/NetworkSecurityConfig.java
index 0a2edff..ebe14691 100644
--- a/core/java/android/security/net/config/NetworkSecurityConfig.java
+++ b/core/java/android/security/net/config/NetworkSecurityConfig.java
@@ -145,6 +145,15 @@
return null;
}
+ /** @hide */
+ public Set<X509Certificate> findAllCertificatesByIssuerAndSignature(X509Certificate cert) {
+ Set<X509Certificate> certs = new ArraySet<X509Certificate>();
+ for (CertificatesEntryRef ref : mCertificatesEntryRefs) {
+ certs.addAll(ref.findAllCertificatesByIssuerAndSignature(cert));
+ }
+ return certs;
+ }
+
/**
* Return a {@link Builder} for the default {@code NetworkSecurityConfig}.
*
diff --git a/core/java/android/security/net/config/ResourceCertificateSource.java b/core/java/android/security/net/config/ResourceCertificateSource.java
index e489c2c..8803c4b 100644
--- a/core/java/android/security/net/config/ResourceCertificateSource.java
+++ b/core/java/android/security/net/config/ResourceCertificateSource.java
@@ -25,6 +25,7 @@
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Collection;
+import java.util.Collections;
import java.util.Set;
import com.android.org.conscrypt.TrustedCertificateIndex;
@@ -100,4 +101,18 @@
}
return anchor.getTrustedCert();
}
+
+ @Override
+ public Set<X509Certificate> findAllByIssuerAndSignature(X509Certificate cert) {
+ ensureInitialized();
+ Set<java.security.cert.TrustAnchor> anchors = mIndex.findAllByIssuerAndSignature(cert);
+ if (anchors.isEmpty()) {
+ return Collections.<X509Certificate>emptySet();
+ }
+ Set<X509Certificate> certs = new ArraySet<X509Certificate>(anchors.size());
+ for (java.security.cert.TrustAnchor anchor : anchors) {
+ certs.add(anchor.getTrustedCert());
+ }
+ return certs;
+ }
}
diff --git a/core/java/android/security/net/config/TrustedCertificateStoreAdapter.java b/core/java/android/security/net/config/TrustedCertificateStoreAdapter.java
index 4a90f82..c2f29be 100644
--- a/core/java/android/security/net/config/TrustedCertificateStoreAdapter.java
+++ b/core/java/android/security/net/config/TrustedCertificateStoreAdapter.java
@@ -42,6 +42,11 @@
}
@Override
+ public Set<X509Certificate> findAllIssuers(X509Certificate cert) {
+ return mConfig.findAllCertificatesByIssuerAndSignature(cert);
+ }
+
+ @Override
public X509Certificate getTrustAnchor(X509Certificate cert) {
TrustAnchor anchor = mConfig.findTrustAnchorBySubjectAndPublicKey(cert);
if (anchor == null) {
diff --git a/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestCertificateSource.java b/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestCertificateSource.java
index 0c36063..4c12c2d 100644
--- a/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestCertificateSource.java
+++ b/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestCertificateSource.java
@@ -16,8 +16,9 @@
package android.security.net.config;
-import java.util.Set;
+import android.util.ArraySet;
import java.security.cert.X509Certificate;
+import java.util.Set;
import com.android.org.conscrypt.TrustedCertificateIndex;
@@ -33,10 +34,12 @@
}
}
+ @Override
public Set<X509Certificate> getCertificates() {
return mCertificates;
}
+ @Override
public X509Certificate findBySubjectAndPublicKey(X509Certificate cert) {
java.security.cert.TrustAnchor anchor = mIndex.findBySubjectAndPublicKey(cert);
if (anchor == null) {
@@ -45,6 +48,7 @@
return anchor.getTrustedCert();
}
+ @Override
public X509Certificate findByIssuerAndSignature(X509Certificate cert) {
java.security.cert.TrustAnchor anchor = mIndex.findByIssuerAndSignature(cert);
if (anchor == null) {
@@ -52,4 +56,13 @@
}
return anchor.getTrustedCert();
}
+
+ @Override
+ public Set<X509Certificate> findAllByIssuerAndSignature(X509Certificate cert) {
+ Set<X509Certificate> certs = new ArraySet<X509Certificate>();
+ for (java.security.cert.TrustAnchor anchor : mIndex.findAllByIssuerAndSignature(cert)) {
+ certs.add(anchor.getTrustedCert());
+ }
+ return certs;
+ }
}