summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndroid (Google) Code Review <android-gerrit@google.com>2009-09-21 20:36:39 -0400
committerAndroid (Google) Code Review <android-gerrit@google.com>2009-09-21 20:36:39 -0400
commit6a93483621c8393a57b50dca1dadaeb48dcb6e38 (patch)
tree6eb68fecf0590cdf8c674cb6b0805808cf6ee9c5
parentbb0d360e281a26b3aa65bf9d7b616e1ef2519220 (diff)
parent5777f56ef4522e39ff9e41e967c399642fc6c6b4 (diff)
downloadlibcore-6a93483621c8393a57b50dca1dadaeb48dcb6e38.zip
libcore-6a93483621c8393a57b50dca1dadaeb48dcb6e38.tar.gz
libcore-6a93483621c8393a57b50dca1dadaeb48dcb6e38.tar.bz2
Merge change 26055 into eclair
* changes: Replaced an O(N) algorithm with an O(1) algorithm. This shaves off 2/3 of the server cert checking time or ~200ms on Sapphire. This is in preparation for tripling the number of certs in an upcoming change.
-rw-r--r--security/src/main/java/org/bouncycastle/jce/provider/IndexedPKIXParameters.java17
-rw-r--r--x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/TrustManagerImpl.java85
2 files changed, 62 insertions, 40 deletions
diff --git a/security/src/main/java/org/bouncycastle/jce/provider/IndexedPKIXParameters.java b/security/src/main/java/org/bouncycastle/jce/provider/IndexedPKIXParameters.java
index e8e834a..03679e2 100644
--- a/security/src/main/java/org/bouncycastle/jce/provider/IndexedPKIXParameters.java
+++ b/security/src/main/java/org/bouncycastle/jce/provider/IndexedPKIXParameters.java
@@ -109,7 +109,7 @@ public class IndexedPKIXParameters extends PKIXParameters {
if (anchor != null) {
return anchor;
}
- } catch (Exception e) {
+ } catch (Exception e) {
Logger.getLogger(IndexedPKIXParameters.class.getName()).log(
Level.WARNING, "Error encoding cert.", e);
}
@@ -125,6 +125,21 @@ public class IndexedPKIXParameters extends PKIXParameters {
}
/**
+ * Returns true if the given certificate is found in the trusted key
+ * store.
+ */
+ public boolean isDirectlyTrusted(X509Certificate cert) {
+ try {
+ Bytes encoded = new Bytes(cert.getEncoded());
+ return encodings.containsKey(encoded);
+ } catch (Exception e) {
+ Logger.getLogger(IndexedPKIXParameters.class.getName()).log(
+ Level.WARNING, "Error encoding cert.", e);
+ return false;
+ }
+ }
+
+ /**
* Wraps a byte[] and adds equals() and hashCode() support.
*/
static class Bytes {
diff --git a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/TrustManagerImpl.java b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/TrustManagerImpl.java
index 5c40b4e..543dfb2 100644
--- a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/TrustManagerImpl.java
+++ b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/TrustManagerImpl.java
@@ -44,11 +44,11 @@ import java.security.cert.CertificateEncodingException;
// END android-added
/**
- *
+ *
* TrustManager implementation. The implementation is based on CertPathValidator
* PKIX and CertificateFactory X509 implementations. This implementations should
* be provided by some certification provider.
- *
+ *
* @see javax.net.ssl.X509TrustManager
*/
public class TrustManagerImpl implements X509TrustManager {
@@ -63,7 +63,7 @@ public class TrustManagerImpl implements X509TrustManager {
/**
* Creates trust manager implementation
- *
+ *
* @param ks
*/
public TrustManagerImpl(KeyStore ks) {
@@ -144,70 +144,77 @@ public class TrustManagerImpl implements X509TrustManager {
throws CertificateException {
if (chain == null || chain.length == 0 || authType == null
|| authType.length() == 0) {
- throw new IllegalArgumentException("null or zero-length parameter");
+ throw new IllegalArgumentException(
+ "null or zero-length parameter");
}
if (err != null) {
throw new CertificateException(err);
}
- // BEGIN android-added
- // Cater for degenerate special case where we can't
- // establish an actual certificate chain the usual way,
- // but have the peer certificate in our trust store.
- if (isDirectlyTrustedCert(chain)) {
- return;
- }
- // END android-added
+// BEGIN android-changed
+ CertificateException ce = null;
try {
- // BEGIN android-changed
- CertPath certPath = factory.generateCertPath(Arrays.asList(chain));
+ CertPath certPath = factory.generateCertPath(
+ Arrays.asList(chain));
if (!Arrays.equals(chain[0].getEncoded(),
- ((X509Certificate)certPath.getCertificates().get(0))
- .getEncoded())) {
- // sanity check failed (shouldn't ever happen, but we are using pretty remote code)
+ certPath.getCertificates().get(0).getEncoded())) {
+ // Sanity check failed (shouldn't ever happen, but we are
+ // using pretty remote code)
throw new CertificateException("Certificate chain error");
}
validator.validate(certPath, params);
- // END android-changed
} catch (InvalidAlgorithmParameterException e) {
- throw new CertificateException(e);
+ ce = new CertificateException(e);
} catch (CertPathValidatorException e) {
- throw new CertificateException(e);
+ ce = new CertificateException(e);
+ }
+ if (ce != null) {
+ // Caters to degenerate special case where we can't
+ // establish an actual certificate chain the usual way
+ // but have the peer certificate in our trust store.
+ if (!isDirectlyTrustedCert(chain)) {
+ throw ce;
+ }
}
}
- // BEGIN android-added
/**
* Checks whether the given chain is just a certificate
* that we have in our trust store.
- *
+ *
* @param chain The certificate chain.
- *
- * @return True if the certificate is in our trust store, false otherwise.
+ *
+ * @return True if the certificate is in our trust store, false otherwise.
*/
private boolean isDirectlyTrustedCert(X509Certificate[] chain) {
byte[] questionable;
if (chain.length == 1) {
- try {
- questionable = chain[0].getEncoded();
- Set<TrustAnchor> anchors = params.getTrustAnchors();
-
- for (TrustAnchor trustAnchor : anchors) {
- byte[] trusted = trustAnchor.getTrustedCert().getEncoded();
-
- if (Arrays.equals(questionable, trusted)) {
- return true;
- }
+ if (params instanceof IndexedPKIXParameters) {
+ IndexedPKIXParameters index = (IndexedPKIXParameters) params;
+ return index.isDirectlyTrusted(chain[0]);
+ } else {
+ try {
+ questionable = chain[0].getEncoded();
+ Set<TrustAnchor> anchors = params.getTrustAnchors();
+
+ for (TrustAnchor trustAnchor : anchors) {
+ byte[] trusted = trustAnchor.getTrustedCert()
+ .getEncoded();
+ if (Arrays.equals(questionable, trusted)) {
+ return true;
+ }
+ }
+ } catch (CertificateEncodingException e) {
+ // Ignore.
+ }
}
- } catch (CertificateEncodingException e) {
- // Ignore.
- }
+
}
return false;
}
- // END android-added
-
+// END android-changed
+
/**
* @see javax.net.ssl.X509TrustManager#getAcceptedIssuers()
*/