summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/IndexedPKIXParameters.java79
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/TrustManagerImpl.java26
2 files changed, 52 insertions, 53 deletions
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/IndexedPKIXParameters.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/IndexedPKIXParameters.java
index c48e331..802ec52 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/IndexedPKIXParameters.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/IndexedPKIXParameters.java
@@ -17,11 +17,8 @@
package org.apache.harmony.xnet.provider.jsse;
import java.security.InvalidAlgorithmParameterException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
import java.security.PublicKey;
import java.security.cert.CertPathValidatorException;
-import java.security.cert.CertificateEncodingException;
import java.security.cert.PKIXParameters;
import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
@@ -37,7 +34,7 @@ import javax.security.auth.x500.X500Principal;
/**
* Indexes trust anchors so they can be found in O(1) time instead of O(N).
*/
-public class IndexedPKIXParameters extends PKIXParameters {
+public final class IndexedPKIXParameters extends PKIXParameters {
private final Map<X500Principal, List<TrustAnchor>> subjectToTrustAnchors
= new HashMap<X500Principal, List<TrustAnchor>>();
@@ -48,22 +45,22 @@ public class IndexedPKIXParameters extends PKIXParameters {
index();
}
- public IndexedPKIXParameters(KeyStore keyStore)
- throws KeyStoreException, InvalidAlgorithmParameterException {
- super(keyStore);
- index();
- }
-
private void index() {
for (TrustAnchor anchor : getTrustAnchors()) {
- X500Principal subject;
- X509Certificate cert = anchor.getTrustedCert();
- if (cert != null) {
- subject = cert.getSubjectX500Principal();
- } else {
- subject = anchor.getCA();
- }
+ index(anchor);
+ }
+ }
+ public void index(TrustAnchor anchor) {
+ X500Principal subject;
+ X509Certificate cert = anchor.getTrustedCert();
+ if (cert != null) {
+ subject = cert.getSubjectX500Principal();
+ } else {
+ subject = anchor.getCA();
+ }
+
+ synchronized (subjectToTrustAnchors) {
List<TrustAnchor> anchors = subjectToTrustAnchors.get(subject);
if (anchors == null) {
anchors = new ArrayList<TrustAnchor>();
@@ -76,25 +73,27 @@ public class IndexedPKIXParameters extends PKIXParameters {
public TrustAnchor findTrustAnchor(X509Certificate cert)
throws CertPathValidatorException {
X500Principal issuer = cert.getIssuerX500Principal();
- List<TrustAnchor> anchors = subjectToTrustAnchors.get(issuer);
- if (anchors == null) {
- return null;
- }
-
Exception verificationException = null;
- for (TrustAnchor anchor : anchors) {
- PublicKey publicKey;
- try {
- X509Certificate caCert = anchor.getTrustedCert();
- if (caCert != null) {
- publicKey = caCert.getPublicKey();
- } else {
- publicKey = anchor.getCAPublicKey();
+ synchronized (subjectToTrustAnchors) {
+ List<TrustAnchor> anchors = subjectToTrustAnchors.get(issuer);
+ if (anchors == null) {
+ return null;
+ }
+
+ for (TrustAnchor anchor : anchors) {
+ PublicKey publicKey;
+ try {
+ X509Certificate caCert = anchor.getTrustedCert();
+ if (caCert != null) {
+ publicKey = caCert.getPublicKey();
+ } else {
+ publicKey = anchor.getCAPublicKey();
+ }
+ cert.verify(publicKey);
+ return anchor;
+ } catch (Exception e) {
+ verificationException = e;
}
- cert.verify(publicKey);
- return anchor;
- } catch (Exception e) {
- verificationException = e;
}
}
@@ -110,14 +109,16 @@ public class IndexedPKIXParameters extends PKIXParameters {
public boolean isTrustAnchor(X509Certificate cert) {
X500Principal subject = cert.getSubjectX500Principal();
- List<TrustAnchor> anchors = subjectToTrustAnchors.get(subject);
- if (anchors == null) {
- return false;
+ synchronized (subjectToTrustAnchors) {
+ List<TrustAnchor> anchors = subjectToTrustAnchors.get(subject);
+ if (anchors == null) {
+ return false;
+ }
+ return isTrustAnchor(cert, anchors);
}
- return isTrustAnchor(cert, anchors);
}
- public static boolean isTrustAnchor(X509Certificate cert, Collection<TrustAnchor> anchors) {
+ private static boolean isTrustAnchor(X509Certificate cert, Collection<TrustAnchor> anchors) {
PublicKey certPublicKey = cert.getPublicKey();
for (TrustAnchor anchor : anchors) {
PublicKey caPublicKey;
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/TrustManagerImpl.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/TrustManagerImpl.java
index 91ad1f8..01af5b3 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/TrustManagerImpl.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/TrustManagerImpl.java
@@ -48,7 +48,7 @@ public class TrustManagerImpl implements X509TrustManager {
private final CertPathValidator validator;
- private final PKIXParameters params;
+ private final IndexedPKIXParameters params;
private final X509Certificate[] acceptedIssuers;
@@ -64,7 +64,7 @@ public class TrustManagerImpl implements X509TrustManager {
public TrustManagerImpl(KeyStore ks) {
CertPathValidator validatorLocal = null;
CertificateFactory factoryLocal = null;
- PKIXParameters paramsLocal = null;
+ IndexedPKIXParameters paramsLocal = null;
X509Certificate[] acceptedIssuersLocal = null;
Exception errLocal = null;
try {
@@ -155,6 +155,15 @@ public class TrustManagerImpl implements X509TrustManager {
}
try {
validator.validate(certPath, params);
+ // Add intermediate CAs to the index to tolerate sites
+ // that assume that the browser will have cached these.
+ // The server certificate is skipped by skipping the
+ // zeroth element of new chain and note that the root CA
+ // will have been removed in cleanupCertChain.
+ // http://b/3404902
+ for (int i = 1; i < newChain.length; i++) {
+ params.index(new TrustAnchor(newChain[i], null));
+ }
} catch (InvalidAlgorithmParameterException e) {
throw new CertificateException(e);
} catch (CertPathValidatorException e) {
@@ -182,7 +191,7 @@ public class TrustManagerImpl implements X509TrustManager {
for (currIndex = 0; currIndex < chain.length; currIndex++) {
// If the current cert is a TrustAnchor, we can ignore the rest of the chain.
// This avoids including "bridge" CA certs that added for legacy compatability.
- if (isTrustAnchor(chain[currIndex])) {
+ if (params.isTrustAnchor(chain[currIndex])) {
currIndex--;
break;
}
@@ -226,17 +235,6 @@ public class TrustManagerImpl implements X509TrustManager {
}
/**
- * Checks whether the given certificate is found in our trust store.
- */
- private boolean isTrustAnchor(X509Certificate cert) {
- if (params instanceof IndexedPKIXParameters) {
- IndexedPKIXParameters index = (IndexedPKIXParameters) params;
- return index.isTrustAnchor(cert);
- }
- return IndexedPKIXParameters.isTrustAnchor(cert, params.getTrustAnchors());
- }
-
- /**
* @see javax.net.ssl.X509TrustManager#getAcceptedIssuers()
*/
public X509Certificate[] getAcceptedIssuers() {