Added CertBlacklister.

This allows us to augment the blacklists with data from other sources.

Change-Id: I05e4f1f65b12346847d7064d2be311c5dc6c0ec2
diff --git a/patches/android.patch b/patches/android.patch
index 1102047..20ed108 100644
--- a/patches/android.patch
+++ b/patches/android.patch
@@ -1,6 +1,6 @@
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/asn1/ASN1InputStream.java bcprov-jdk16-146/org/bouncycastle/asn1/ASN1InputStream.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/asn1/ASN1InputStream.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/asn1/ASN1InputStream.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/asn1/ASN1InputStream.java	2012-05-11 05:31:26.610725423 +0000
 @@ -363,7 +363,9 @@
              case BMP_STRING:
                  return new DERBMPString(bytes);
@@ -14,7 +14,7 @@
              case GENERALIZED_TIME:
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/asn1/ASN1Null.java bcprov-jdk16-146/org/bouncycastle/asn1/ASN1Null.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/asn1/ASN1Null.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/asn1/ASN1Null.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/asn1/ASN1Null.java	2012-05-11 05:31:26.610725423 +0000
 @@ -8,9 +8,11 @@
  public abstract class ASN1Null
      extends ASN1Object
@@ -30,7 +30,7 @@
      {
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/asn1/DERBoolean.java bcprov-jdk16-146/org/bouncycastle/asn1/DERBoolean.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/asn1/DERBoolean.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/asn1/DERBoolean.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/asn1/DERBoolean.java	2012-05-11 05:31:26.610725423 +0000
 @@ -5,7 +5,9 @@
  public class DERBoolean
      extends ASN1Object
@@ -104,7 +104,7 @@
      }
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/asn1/DERNull.java bcprov-jdk16-146/org/bouncycastle/asn1/DERNull.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/asn1/DERNull.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/asn1/DERNull.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/asn1/DERNull.java	2012-05-11 05:31:26.610725423 +0000
 @@ -10,9 +10,13 @@
  {
      public static final DERNull INSTANCE = new DERNull();
@@ -123,7 +123,7 @@
  
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/asn1/DERObjectIdentifier.java bcprov-jdk16-146/org/bouncycastle/asn1/DERObjectIdentifier.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/asn1/DERObjectIdentifier.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/asn1/DERObjectIdentifier.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/asn1/DERObjectIdentifier.java	2012-05-11 05:31:26.610725423 +0000
 @@ -110,7 +110,13 @@
              }
          }
@@ -156,7 +156,7 @@
      public String getId()
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/asn1/DERPrintableString.java bcprov-jdk16-146/org/bouncycastle/asn1/DERPrintableString.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/asn1/DERPrintableString.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/asn1/DERPrintableString.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/asn1/DERPrintableString.java	2012-05-11 05:31:26.620725599 +0000
 @@ -9,7 +9,9 @@
      extends ASN1Object
      implements DERString
@@ -192,7 +192,7 @@
      public String getString()
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/asn1/cms/ContentInfo.java bcprov-jdk16-146/org/bouncycastle/asn1/cms/ContentInfo.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/asn1/cms/ContentInfo.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/asn1/cms/ContentInfo.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/asn1/cms/ContentInfo.java	2012-05-11 05:31:26.620725599 +0000
 @@ -12,7 +12,9 @@
  
  public class ContentInfo
@@ -206,7 +206,7 @@
      private DEREncodable        content;
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java bcprov-jdk16-146/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java	2012-05-11 05:31:26.610725423 +0000
 @@ -37,10 +37,13 @@
      public static EncryptedPrivateKeyInfo getInstance(
          Object  obj)
@@ -224,7 +224,7 @@
              return new EncryptedPrivateKeyInfo((ASN1Sequence)obj);
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java bcprov-jdk16-146/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java	2012-05-11 05:31:26.610725423 +0000
 @@ -10,8 +10,10 @@
      //
      static final ASN1ObjectIdentifier    pkcs_1                    = new ASN1ObjectIdentifier("1.2.840.113549.1.1");
@@ -282,7 +282,7 @@
      static final ASN1ObjectIdentifier    id_hmacWithSHA512       = digestAlgorithm.branch("11");
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java bcprov-jdk16-146/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java	2012-05-11 05:31:26.610725423 +0000
 @@ -19,7 +19,9 @@
      private AlgorithmIdentifier maskGenAlgorithm;
      private AlgorithmIdentifier pSourceAlgorithm;
@@ -296,7 +296,7 @@
      
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java bcprov-jdk16-146/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java	2012-05-11 05:31:26.610725423 +0000
 @@ -20,7 +20,9 @@
      private DERInteger          saltLength;
      private DERInteger          trailerField;
@@ -310,7 +310,7 @@
      public final static DERInteger          DEFAULT_TRAILER_FIELD = new DERInteger(1);
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/asn1/util/ASN1Dump.java bcprov-jdk16-146/org/bouncycastle/asn1/util/ASN1Dump.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/asn1/util/ASN1Dump.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/asn1/util/ASN1Dump.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/asn1/util/ASN1Dump.java	2012-05-11 05:31:26.620725599 +0000
 @@ -79,7 +79,9 @@
              {
                  Object  o = e.nextElement();
@@ -324,7 +324,7 @@
                      buf.append("NULL");
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/asn1/x509/AttCertIssuer.java bcprov-jdk16-146/org/bouncycastle/asn1/x509/AttCertIssuer.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/asn1/x509/AttCertIssuer.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/asn1/x509/AttCertIssuer.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/asn1/x509/AttCertIssuer.java	2012-05-11 05:31:26.610725423 +0000
 @@ -45,7 +45,7 @@
          ASN1TaggedObject obj,
          boolean          explicit)
@@ -336,7 +336,7 @@
      /**
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/asn1/x509/BasicConstraints.java bcprov-jdk16-146/org/bouncycastle/asn1/x509/BasicConstraints.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/asn1/x509/BasicConstraints.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/asn1/x509/BasicConstraints.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/asn1/x509/BasicConstraints.java	2012-05-11 05:31:26.610725423 +0000
 @@ -14,7 +14,9 @@
  public class BasicConstraints
      extends ASN1Encodable
@@ -383,7 +383,7 @@
  
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java bcprov-jdk16-146/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java	2012-05-11 05:31:26.610725423 +0000
 @@ -96,11 +96,15 @@
          }
          if (onlyContainsUserCerts)
@@ -422,7 +422,7 @@
          seq = new DERSequence(vec);
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/asn1/x509/X509Extensions.java bcprov-jdk16-146/org/bouncycastle/asn1/x509/X509Extensions.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/asn1/x509/X509Extensions.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/asn1/x509/X509Extensions.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/asn1/x509/X509Extensions.java	2012-05-11 05:31:26.610725423 +0000
 @@ -400,7 +400,9 @@
  
              if (ext.isCritical())
@@ -436,7 +436,7 @@
              v.add(ext.getValue());
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/asn1/x509/X509Name.java bcprov-jdk16-146/org/bouncycastle/asn1/x509/X509Name.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/asn1/x509/X509Name.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/asn1/x509/X509Name.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/asn1/x509/X509Name.java	2012-05-11 05:31:26.610725423 +0000
 @@ -249,8 +249,10 @@
       */
      public static final Hashtable SymbolLookUp = DefaultLookUp;
@@ -474,7 +474,7 @@
              String              name = token.substring(0, index);
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/asn1/x509/X509NameTokenizer.java bcprov-jdk16-146/org/bouncycastle/asn1/x509/X509NameTokenizer.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/asn1/x509/X509NameTokenizer.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/asn1/x509/X509NameTokenizer.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/asn1/x509/X509NameTokenizer.java	2012-05-11 05:31:26.610725423 +0000
 @@ -58,6 +58,17 @@
                  }
                  else
@@ -502,7 +502,7 @@
 \ No newline at end of file
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/crypto/PBEParametersGenerator.java bcprov-jdk16-146/org/bouncycastle/crypto/PBEParametersGenerator.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/crypto/PBEParametersGenerator.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/crypto/PBEParametersGenerator.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/crypto/PBEParametersGenerator.java	2012-05-11 05:31:26.620725599 +0000
 @@ -136,7 +136,8 @@
      public static byte[] PKCS12PasswordToBytes(
          char[]  password)
@@ -522,7 +522,7 @@
  }
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/crypto/digests/OpenSSLDigest.java bcprov-jdk16-146/org/bouncycastle/crypto/digests/OpenSSLDigest.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/crypto/digests/OpenSSLDigest.java	1970-01-01 00:00:00.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/crypto/digests/OpenSSLDigest.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/crypto/digests/OpenSSLDigest.java	2012-05-11 05:31:26.620725599 +0000
 @@ -0,0 +1,159 @@
 +/*
 + * Copyright (C) 2008 The Android Open Source Project
@@ -685,7 +685,7 @@
 +}
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/crypto/engines/RC2Engine.java bcprov-jdk16-146/org/bouncycastle/crypto/engines/RC2Engine.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/crypto/engines/RC2Engine.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/crypto/engines/RC2Engine.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/crypto/engines/RC2Engine.java	2012-05-11 05:31:26.620725599 +0000
 @@ -313,4 +313,4 @@
          out[outOff + 6] = (byte)x76;
          out[outOff + 7] = (byte)(x76 >> 8);
@@ -695,7 +695,7 @@
 \ No newline at end of file
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/crypto/generators/DHParametersHelper.java bcprov-jdk16-146/org/bouncycastle/crypto/generators/DHParametersHelper.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/crypto/generators/DHParametersHelper.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/crypto/generators/DHParametersHelper.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/crypto/generators/DHParametersHelper.java	2012-05-11 05:31:26.620725599 +0000
 @@ -3,10 +3,17 @@
  import java.math.BigInteger;
  import java.security.SecureRandom;
@@ -748,7 +748,7 @@
      }
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/crypto/macs/HMac.java bcprov-jdk16-146/org/bouncycastle/crypto/macs/HMac.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/crypto/macs/HMac.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/crypto/macs/HMac.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/crypto/macs/HMac.java	2012-05-11 05:31:26.620725599 +0000
 @@ -32,23 +32,23 @@
      {
          blockLengths = new Hashtable();
@@ -790,7 +790,7 @@
      private static int getByteLength(
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/crypto/signers/RSADigestSigner.java bcprov-jdk16-146/org/bouncycastle/crypto/signers/RSADigestSigner.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/crypto/signers/RSADigestSigner.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/crypto/signers/RSADigestSigner.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/crypto/signers/RSADigestSigner.java	2012-05-11 05:31:26.620725599 +0000
 @@ -46,8 +46,10 @@
          oidMap.put("SHA-384", NISTObjectIdentifiers.id_sha384);
          oidMap.put("SHA-512", NISTObjectIdentifiers.id_sha512);
@@ -806,7 +806,7 @@
  
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/crypto/util/PrivateKeyFactory.java bcprov-jdk16-146/org/bouncycastle/crypto/util/PrivateKeyFactory.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/crypto/util/PrivateKeyFactory.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/crypto/util/PrivateKeyFactory.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/crypto/util/PrivateKeyFactory.java	2012-05-11 05:31:26.630725775 +0000
 @@ -12,7 +12,9 @@
  import org.bouncycastle.asn1.DERObject;
  import org.bouncycastle.asn1.DERObjectIdentifier;
@@ -888,7 +888,7 @@
  
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/crypto/util/PublicKeyFactory.java bcprov-jdk16-146/org/bouncycastle/crypto/util/PublicKeyFactory.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/crypto/util/PublicKeyFactory.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/crypto/util/PublicKeyFactory.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/crypto/util/PublicKeyFactory.java	2012-05-11 05:31:26.630725775 +0000
 @@ -15,12 +15,16 @@
  import org.bouncycastle.asn1.DERObjectIdentifier;
  import org.bouncycastle.asn1.DEROctetString;
@@ -967,7 +967,7 @@
  
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/ECNamedCurveTable.java bcprov-jdk16-146/org/bouncycastle/jce/ECNamedCurveTable.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/ECNamedCurveTable.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/ECNamedCurveTable.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/ECNamedCurveTable.java	2012-05-11 05:31:26.630725775 +0000
 @@ -3,7 +3,9 @@
  import org.bouncycastle.asn1.DERObjectIdentifier;
  import org.bouncycastle.asn1.nist.NISTNamedCurves;
@@ -1031,7 +1031,7 @@
      }
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/PKCS10CertificationRequest.java bcprov-jdk16-146/org/bouncycastle/jce/PKCS10CertificationRequest.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/PKCS10CertificationRequest.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/PKCS10CertificationRequest.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/PKCS10CertificationRequest.java	2012-05-11 05:31:26.630725775 +0000
 @@ -80,15 +80,20 @@
  
      static
@@ -1281,7 +1281,7 @@
              return digestAlgOID.getId();            
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/BouncyCastleProvider.java bcprov-jdk16-146/org/bouncycastle/jce/provider/BouncyCastleProvider.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/BouncyCastleProvider.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/BouncyCastleProvider.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/BouncyCastleProvider.java	2012-05-11 05:31:26.630725775 +0000
 @@ -45,7 +45,10 @@
  {
      private static String info = "BouncyCastle Security Provider v1.46";
@@ -2443,9 +2443,184 @@
  
      public void setParameter(String parameterName, Object parameter)
      {
+diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/CertBlacklist.java bcprov-jdk16-146/org/bouncycastle/jce/provider/CertBlacklist.java
+--- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/CertBlacklist.java	1970-01-01 00:00:00.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/CertBlacklist.java	2012-05-11 05:31:26.630725775 +0000
+@@ -0,0 +1,171 @@
++/*
++ * Copyright (C) 2012 The Android Open Source Project
++ *
++ * Licensed under the Apache License, Version 2.0 (the "License");
++ * you may not use this file except in compliance with the License.
++ * You may obtain a copy of the License at
++ *
++ *      http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the License for the specific language governing permissions and
++ * limitations under the License.
++ */
++
++package org.bouncycastle.jce.provider;
++
++import java.io.FileNotFoundException;
++import java.io.IOException;
++import java.math.BigInteger;
++import java.security.PublicKey;
++import java.util.ArrayList;
++import java.util.Arrays;
++import java.util.Collections;
++import java.util.HashSet;
++import java.util.List;
++import java.util.Set;
++
++import libcore.io.IoUtils;
++import org.bouncycastle.crypto.Digest;
++import org.bouncycastle.crypto.digests.OpenSSLDigest;
++import org.bouncycastle.util.encoders.Hex;
++
++public class CertBlacklist {
++
++    private static final String ANDROID_DATA = System.getenv("ANDROID_DATA");
++    private static final String BLACKLIST_ROOT = ANDROID_DATA + "/misc/keychain/";
++    public static final String DEFAULT_PUBKEY_BLACKLIST_PATH = BLACKLIST_ROOT + "pubkey_blacklist.txt";
++    public static final String DEFAULT_SERIAL_BLACKLIST_PATH = BLACKLIST_ROOT + "serial_blacklist.txt";
++
++    // public for testing
++    public final Set<BigInteger> serialBlacklist;
++    public final Set<byte[]> pubkeyBlacklist;
++
++    public CertBlacklist() {
++        this(DEFAULT_PUBKEY_BLACKLIST_PATH, DEFAULT_SERIAL_BLACKLIST_PATH);
++    }
++
++    /** Test only interface, not for public use */
++    public CertBlacklist(String pubkeyBlacklistPath, String serialBlacklistPath) {
++        serialBlacklist = readSerialBlackList(serialBlacklistPath);
++        pubkeyBlacklist = readPublicKeyBlackList(pubkeyBlacklistPath);
++    }
++
++    private static boolean isHex(String value) {
++        try {
++            new BigInteger(value, 16);
++            return true;
++        } catch (NumberFormatException e) {
++            System.logW("Could not parse hex value " + value, e);
++            return false;
++        }
++    }
++
++    private static boolean isPubkeyHash(String value) {
++        if (value.length() != 40) {
++            System.logW("Invalid pubkey hash length: " + value.length());
++            return false;
++         }
++         return isHex(value);
++    }
++
++    private static String readBlacklist(String path) {
++        try {
++            return IoUtils.readFileAsString(path);
++        } catch (FileNotFoundException ignored) {
++        } catch (IOException e) {
++            System.logW("Could not read blacklist", e);
++        }
++        return "";
++    }
++
++    private static final Set<BigInteger> readSerialBlackList(String path) {
++
++        // start out with a base set of known bad values
++        Set<BigInteger> bl = new HashSet<BigInteger>(Arrays.asList(
++            // From http://src.chromium.org/viewvc/chrome/trunk/src/net/base/x509_certificate.cc?revision=78748&view=markup
++            // Not a real certificate. For testing only.
++            new BigInteger("077a59bcd53459601ca6907267a6dd1c", 16),
++            new BigInteger("047ecbe9fca55f7bd09eae36e10cae1e", 16),
++            new BigInteger("d8f35f4eb7872b2dab0692e315382fb0", 16),
++            new BigInteger("b0b7133ed096f9b56fae91c874bd3ac0", 16),
++            new BigInteger("9239d5348f40d1695a745470e1f23f43", 16),
++            new BigInteger("e9028b9578e415dc1a710a2b88154447", 16),
++            new BigInteger("d7558fdaf5f1105bb213282b707729a3", 16),
++            new BigInteger("f5c86af36162f13a64f54f6dc9587c06", 16),
++            new BigInteger("392a434f0e07df1f8aa305de34e0c229", 16),
++            new BigInteger("3e75ced46b693021218830ae86a82a71", 16)
++        ));
++
++        // attempt to augment it with values taken from gservices
++        String serialBlacklist = readBlacklist(path);
++        if (!serialBlacklist.equals("")) {
++            for(String value : serialBlacklist.split(",")) {
++                try {
++                    bl.add(new BigInteger(value, 16));
++                } catch (NumberFormatException e) {
++                    System.logW("Tried to blacklist invalid serial number " + value, e);
++                }
++            }
++        }
++
++        // whether that succeeds or fails, send it on its merry way
++        return Collections.unmodifiableSet(bl);
++    }
++
++    private static final Set<byte[]> readPublicKeyBlackList(String path) {
++
++        // start out with a base set of known bad values
++        Set<byte[]> bl = new HashSet<byte[]>(Arrays.asList(
++            // From http://src.chromium.org/viewvc/chrome/branches/782/src/net/base/x509_certificate.cc?r1=98750&r2=98749&pathrev=98750
++            // C=NL, O=DigiNotar, CN=DigiNotar Root CA/emailAddress=info@diginotar.nl
++            "410f36363258f30b347d12ce4863e433437806a8".getBytes(),
++            // Subject: CN=DigiNotar Cyber CA
++            // Issuer: CN=GTE CyberTrust Global Root
++            "ba3e7bd38cd7e1e6b9cd4c219962e59d7a2f4e37".getBytes(),
++            // Subject: CN=DigiNotar Services 1024 CA
++            // Issuer: CN=Entrust.net
++            "e23b8d105f87710a68d9248050ebefc627be4ca6".getBytes(),
++            // Subject: CN=DigiNotar PKIoverheid CA Organisatie - G2
++            // Issuer: CN=Staat der Nederlanden Organisatie CA - G2
++            "7b2e16bc39bcd72b456e9f055d1de615b74945db".getBytes(),
++            // Subject: CN=DigiNotar PKIoverheid CA Overheid en Bedrijven
++            // Issuer: CN=Staat der Nederlanden Overheid CA
++            "e8f91200c65cee16e039b9f883841661635f81c5".getBytes(),
++            // From http://src.chromium.org/viewvc/chrome?view=rev&revision=108479
++            // Subject: O=Digicert Sdn. Bhd.
++            // Issuer: CN=GTE CyberTrust Global Root
++            "0129bcd5b448ae8d2496d1c3e19723919088e152".getBytes()
++        ));
++
++        // attempt to augment it with values taken from gservices
++        String pubkeyBlacklist = readBlacklist(path);
++        if (!pubkeyBlacklist.equals("")) {
++            for (String value : pubkeyBlacklist.split(",")) {
++                if (isPubkeyHash(value)) {
++                    bl.add(Hex.decode(value));
++                } else {
++                    System.logW("Tried to blacklist invalid pubkey " + value);
++                }
++            }
++        }
++
++        return bl;
++    }
++
++    public boolean isPublicKeyBlackListed(PublicKey publicKey) {
++        byte[] encoded = publicKey.getEncoded();
++        Digest digest = new OpenSSLDigest.SHA1();
++        digest.update(encoded, 0, encoded.length);
++        byte[] out = new byte[digest.getDigestSize()];
++        digest.doFinal(out, 0);
++        return pubkeyBlacklist.contains(out);
++    }
++
++    public boolean isSerialNumberBlackListed(BigInteger serial) {
++        return serialBlacklist.contains(serial);
++    }
++
++}
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java bcprov-jdk16-146/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java	2012-05-11 05:31:26.630725775 +0000
 @@ -24,6 +24,7 @@
  import java.security.spec.DSAPublicKeySpec;
  import java.text.ParseException;
@@ -2627,7 +2802,7 @@
          CRLDistPoint crldp, ExtendedPKIXParameters pkixParams)
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JCEBlockCipher.java bcprov-jdk16-146/org/bouncycastle/jce/provider/JCEBlockCipher.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JCEBlockCipher.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JCEBlockCipher.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JCEBlockCipher.java	2012-05-11 05:31:26.630725775 +0000
 @@ -17,8 +17,10 @@
  import javax.crypto.ShortBufferException;
  import javax.crypto.spec.IvParameterSpec;
@@ -3092,7 +3267,7 @@
       */
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JCEDHKeyAgreement.java bcprov-jdk16-146/org/bouncycastle/jce/provider/JCEDHKeyAgreement.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JCEDHKeyAgreement.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JCEDHKeyAgreement.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JCEDHKeyAgreement.java	2012-05-11 05:31:26.630725775 +0000
 @@ -36,10 +36,12 @@
  
      static
@@ -3112,7 +3287,7 @@
          algorithms.put("DESEDE", i192);
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JCEDigestUtil.java bcprov-jdk16-146/org/bouncycastle/jce/provider/JCEDigestUtil.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JCEDigestUtil.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JCEDigestUtil.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JCEDigestUtil.java	2012-05-11 05:31:26.630725775 +0000
 @@ -12,7 +12,9 @@
  import org.bouncycastle.crypto.Digest;
  import org.bouncycastle.crypto.digests.MD5Digest;
@@ -3195,7 +3370,7 @@
              || (sha512.contains(digest1) && sha512.contains(digest2))
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JCEECPrivateKey.java bcprov-jdk16-146/org/bouncycastle/jce/provider/JCEECPrivateKey.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JCEECPrivateKey.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JCEECPrivateKey.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JCEECPrivateKey.java	2012-05-11 05:31:26.630725775 +0000
 @@ -20,7 +20,9 @@
  import org.bouncycastle.asn1.DERObject;
  import org.bouncycastle.asn1.DERObjectIdentifier;
@@ -3267,7 +3442,7 @@
              info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params.getDERObject()), keyStructure.getDERObject());
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JCEECPublicKey.java bcprov-jdk16-146/org/bouncycastle/jce/provider/JCEECPublicKey.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JCEECPublicKey.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JCEECPublicKey.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JCEECPublicKey.java	2012-05-11 05:31:26.630725775 +0000
 @@ -20,8 +20,10 @@
  import org.bouncycastle.asn1.DERObjectIdentifier;
  import org.bouncycastle.asn1.DEROctetString;
@@ -3515,7 +3690,7 @@
              {
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JCEKeyGenerator.java bcprov-jdk16-146/org/bouncycastle/jce/provider/JCEKeyGenerator.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JCEKeyGenerator.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JCEKeyGenerator.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JCEKeyGenerator.java	2012-05-11 05:31:26.630725775 +0000
 @@ -57,6 +57,11 @@
      {
          try
@@ -3751,7 +3926,7 @@
  }
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JCEMac.java bcprov-jdk16-146/org/bouncycastle/jce/provider/JCEMac.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JCEMac.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JCEMac.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JCEMac.java	2012-05-11 05:31:26.630725775 +0000
 @@ -11,25 +11,39 @@
  
  import org.bouncycastle.crypto.CipherParameters;
@@ -4281,7 +4456,7 @@
  }
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JCERSACipher.java bcprov-jdk16-146/org/bouncycastle/jce/provider/JCERSACipher.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JCERSACipher.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JCERSACipher.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JCERSACipher.java	2012-05-11 05:31:26.630725775 +0000
 @@ -535,48 +535,50 @@
          }
      }
@@ -4379,7 +4554,7 @@
  }
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JCERSAPrivateCrtKey.java bcprov-jdk16-146/org/bouncycastle/jce/provider/JCERSAPrivateCrtKey.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JCERSAPrivateCrtKey.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JCERSAPrivateCrtKey.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JCERSAPrivateCrtKey.java	2012-05-11 05:31:26.630725775 +0000
 @@ -125,7 +125,9 @@
       */
      public byte[] getEncoded()
@@ -4393,7 +4568,7 @@
      }
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JCERSAPrivateKey.java bcprov-jdk16-146/org/bouncycastle/jce/provider/JCERSAPrivateKey.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JCERSAPrivateKey.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JCERSAPrivateKey.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JCERSAPrivateKey.java	2012-05-11 05:31:26.630725775 +0000
 @@ -77,7 +77,9 @@
  
      public byte[] getEncoded()
@@ -4407,7 +4582,7 @@
      }
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JCERSAPublicKey.java bcprov-jdk16-146/org/bouncycastle/jce/provider/JCERSAPublicKey.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JCERSAPublicKey.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JCERSAPublicKey.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JCERSAPublicKey.java	2012-05-11 05:31:26.630725775 +0000
 @@ -90,7 +90,9 @@
  
      public byte[] getEncoded()
@@ -4421,7 +4596,7 @@
      }
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JCESecretKeyFactory.java bcprov-jdk16-146/org/bouncycastle/jce/provider/JCESecretKeyFactory.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JCESecretKeyFactory.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JCESecretKeyFactory.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JCESecretKeyFactory.java	2012-05-11 05:31:26.630725775 +0000
 @@ -250,29 +250,31 @@
          }
      }
@@ -4598,7 +4773,7 @@
  }
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JCEStreamCipher.java bcprov-jdk16-146/org/bouncycastle/jce/provider/JCEStreamCipher.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JCEStreamCipher.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JCEStreamCipher.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JCEStreamCipher.java	2012-05-11 05:31:26.630725775 +0000
 @@ -13,20 +13,26 @@
  import javax.crypto.ShortBufferException;
  import javax.crypto.spec.IvParameterSpec;
@@ -4904,7 +5079,7 @@
       */
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JDKAlgorithmParameterGenerator.java bcprov-jdk16-146/org/bouncycastle/jce/provider/JDKAlgorithmParameterGenerator.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JDKAlgorithmParameterGenerator.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JDKAlgorithmParameterGenerator.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JDKAlgorithmParameterGenerator.java	2012-05-11 05:31:26.630725775 +0000
 @@ -11,18 +11,24 @@
  import javax.crypto.spec.DHGenParameterSpec;
  import javax.crypto.spec.DHParameterSpec;
@@ -5330,7 +5505,7 @@
  }
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JDKAlgorithmParameters.java bcprov-jdk16-146/org/bouncycastle/jce/provider/JDKAlgorithmParameters.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JDKAlgorithmParameters.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JDKAlgorithmParameters.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JDKAlgorithmParameters.java	2012-05-11 05:31:26.630725775 +0000
 @@ -10,21 +10,27 @@
  import org.bouncycastle.asn1.DERObjectIdentifier;
  import org.bouncycastle.asn1.DEROctetString;
@@ -6830,7 +7005,7 @@
  }
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JDKDSASigner.java bcprov-jdk16-146/org/bouncycastle/jce/provider/JDKDSASigner.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JDKDSASigner.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JDKDSASigner.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JDKDSASigner.java	2012-05-11 05:31:26.630725775 +0000
 @@ -23,13 +23,17 @@
  import org.bouncycastle.crypto.Digest;
  import org.bouncycastle.crypto.digests.NullDigest;
@@ -6981,7 +7156,7 @@
          extends JDKDSASigner
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JDKDigestSignature.java bcprov-jdk16-146/org/bouncycastle/jce/provider/JDKDigestSignature.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JDKDigestSignature.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JDKDigestSignature.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JDKDigestSignature.java	2012-05-11 05:31:26.630725775 +0000
 @@ -23,15 +23,21 @@
  import org.bouncycastle.crypto.AsymmetricBlockCipher;
  import org.bouncycastle.crypto.CipherParameters;
@@ -7157,7 +7332,7 @@
  }
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JDKKeyFactory.java bcprov-jdk16-146/org/bouncycastle/jce/provider/JDKKeyFactory.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JDKKeyFactory.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JDKKeyFactory.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JDKKeyFactory.java	2012-05-11 05:31:26.630725775 +0000
 @@ -36,17 +36,21 @@
  import org.bouncycastle.asn1.pkcs.RSAPrivateKeyStructure;
  import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
@@ -7543,7 +7718,7 @@
  }
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JDKKeyPairGenerator.java bcprov-jdk16-146/org/bouncycastle/jce/provider/JDKKeyPairGenerator.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JDKKeyPairGenerator.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JDKKeyPairGenerator.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JDKKeyPairGenerator.java	2012-05-11 05:31:26.630725775 +0000
 @@ -6,9 +6,11 @@
  import org.bouncycastle.crypto.generators.DHParametersGenerator;
  import org.bouncycastle.crypto.generators.DSAKeyPairGenerator;
@@ -7887,7 +8062,7 @@
  }
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JDKKeyStore.java bcprov-jdk16-146/org/bouncycastle/jce/provider/JDKKeyStore.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JDKKeyStore.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JDKKeyStore.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JDKKeyStore.java	2012-05-11 05:31:26.630725775 +0000
 @@ -39,7 +39,12 @@
  import org.bouncycastle.crypto.CipherParameters;
  import org.bouncycastle.crypto.Digest;
@@ -7990,7 +8165,7 @@
  }
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JDKMessageDigest.java bcprov-jdk16-146/org/bouncycastle/jce/provider/JDKMessageDigest.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JDKMessageDigest.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JDKMessageDigest.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JDKMessageDigest.java	2012-05-11 05:31:26.630725775 +0000
 @@ -57,36 +57,38 @@
          {
              super(new SHA1Digest());
@@ -8437,7 +8612,7 @@
  }
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JDKPKCS12KeyStore.java bcprov-jdk16-146/org/bouncycastle/jce/provider/JDKPKCS12KeyStore.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/JDKPKCS12KeyStore.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JDKPKCS12KeyStore.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/JDKPKCS12KeyStore.java	2012-05-11 05:31:26.630725775 +0000
 @@ -260,10 +260,13 @@
              }
          }
@@ -8607,7 +8782,7 @@
                  return null;
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/PBE.java bcprov-jdk16-146/org/bouncycastle/jce/provider/PBE.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/PBE.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/PBE.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/PBE.java	2012-05-11 05:31:26.630725775 +0000
 @@ -7,12 +7,18 @@
  
  import org.bouncycastle.crypto.CipherParameters;
@@ -8682,7 +8857,7 @@
                      break;
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/PKIXCertPath.java bcprov-jdk16-146/org/bouncycastle/jce/provider/PKIXCertPath.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/PKIXCertPath.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/PKIXCertPath.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/PKIXCertPath.java	2012-05-11 05:31:26.630725775 +0000
 @@ -33,7 +33,9 @@
  import org.bouncycastle.asn1.pkcs.ContentInfo;
  import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
@@ -8747,7 +8922,7 @@
              throw new CertificateEncodingException("unsupported encoding: " + encoding);
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java bcprov-jdk16-146/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java	2012-05-11 05:31:26.630725775 +0000
 @@ -1,5 +1,8 @@
  package org.bouncycastle.jce.provider;
  
@@ -8765,88 +8940,17 @@
  import java.util.HashSet;
  import java.util.Iterator;
  import java.util.List;
-@@ -23,6 +27,10 @@
- import org.bouncycastle.asn1.DEREncodable;
- import org.bouncycastle.asn1.DERObjectIdentifier;
- import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-+// BEGIN android-added
-+import org.bouncycastle.crypto.Digest;
-+import org.bouncycastle.crypto.digests.OpenSSLDigest;
-+// END android-added
- import org.bouncycastle.jce.exception.ExtCertPathValidatorException;
- import org.bouncycastle.x509.ExtendedPKIXParameters;
- 
-@@ -33,6 +41,69 @@
+@@ -33,6 +37,9 @@
  public class PKIXCertPathValidatorSpi
          extends CertPathValidatorSpi
  {
 +    // BEGIN android-added
-+
-+    // From http://src.chromium.org/viewvc/chrome/trunk/src/net/base/x509_certificate.cc?revision=78748&view=markup
-+    private static final Set<BigInteger> SERIAL_BLACKLIST = new HashSet<BigInteger>(Arrays.asList(
-+        // Not a real certificate. For testing only.
-+        new BigInteger(1, new byte[] {(byte)0x07,(byte)0x7a,(byte)0x59,(byte)0xbc,(byte)0xd5,(byte)0x34,(byte)0x59,(byte)0x60,(byte)0x1c,(byte)0xa6,(byte)0x90,(byte)0x72,(byte)0x67,(byte)0xa6,(byte)0xdd,(byte)0x1c}),
-+
-+        new BigInteger(1, new byte[] {(byte)0x04,(byte)0x7e,(byte)0xcb,(byte)0xe9,(byte)0xfc,(byte)0xa5,(byte)0x5f,(byte)0x7b,(byte)0xd0,(byte)0x9e,(byte)0xae,(byte)0x36,(byte)0xe1,(byte)0x0c,(byte)0xae,(byte)0x1e}),
-+        new BigInteger(1, new byte[] {(byte)0xd8,(byte)0xf3,(byte)0x5f,(byte)0x4e,(byte)0xb7,(byte)0x87,(byte)0x2b,(byte)0x2d,(byte)0xab,(byte)0x06,(byte)0x92,(byte)0xe3,(byte)0x15,(byte)0x38,(byte)0x2f,(byte)0xb0}),
-+        new BigInteger(1, new byte[] {(byte)0xb0,(byte)0xb7,(byte)0x13,(byte)0x3e,(byte)0xd0,(byte)0x96,(byte)0xf9,(byte)0xb5,(byte)0x6f,(byte)0xae,(byte)0x91,(byte)0xc8,(byte)0x74,(byte)0xbd,(byte)0x3a,(byte)0xc0}),
-+        new BigInteger(1, new byte[] {(byte)0x92,(byte)0x39,(byte)0xd5,(byte)0x34,(byte)0x8f,(byte)0x40,(byte)0xd1,(byte)0x69,(byte)0x5a,(byte)0x74,(byte)0x54,(byte)0x70,(byte)0xe1,(byte)0xf2,(byte)0x3f,(byte)0x43}),
-+        new BigInteger(1, new byte[] {(byte)0xe9,(byte)0x02,(byte)0x8b,(byte)0x95,(byte)0x78,(byte)0xe4,(byte)0x15,(byte)0xdc,(byte)0x1a,(byte)0x71,(byte)0x0a,(byte)0x2b,(byte)0x88,(byte)0x15,(byte)0x44,(byte)0x47}),
-+        new BigInteger(1, new byte[] {(byte)0xd7,(byte)0x55,(byte)0x8f,(byte)0xda,(byte)0xf5,(byte)0xf1,(byte)0x10,(byte)0x5b,(byte)0xb2,(byte)0x13,(byte)0x28,(byte)0x2b,(byte)0x70,(byte)0x77,(byte)0x29,(byte)0xa3}),
-+        new BigInteger(1, new byte[] {(byte)0xf5,(byte)0xc8,(byte)0x6a,(byte)0xf3,(byte)0x61,(byte)0x62,(byte)0xf1,(byte)0x3a,(byte)0x64,(byte)0xf5,(byte)0x4f,(byte)0x6d,(byte)0xc9,(byte)0x58,(byte)0x7c,(byte)0x06}),
-+        new BigInteger(1, new byte[] {(byte)0x39,(byte)0x2a,(byte)0x43,(byte)0x4f,(byte)0x0e,(byte)0x07,(byte)0xdf,(byte)0x1f,(byte)0x8a,(byte)0xa3,(byte)0x05,(byte)0xde,(byte)0x34,(byte)0xe0,(byte)0xc2,(byte)0x29}),
-+        new BigInteger(1, new byte[] {(byte)0x3e,(byte)0x75,(byte)0xce,(byte)0xd4,(byte)0x6b,(byte)0x69,(byte)0x30,(byte)0x21,(byte)0x21,(byte)0x88,(byte)0x30,(byte)0xae,(byte)0x86,(byte)0xa8,(byte)0x2a,(byte)0x71})
-+    ));
-+
-+    private static final byte[][] PUBLIC_KEY_SHA1_BLACKLIST = {
-+        // From http://src.chromium.org/viewvc/chrome/branches/782/src/net/base/x509_certificate.cc?r1=98750&r2=98749&pathrev=98750
-+        // C=NL, O=DigiNotar, CN=DigiNotar Root CA/emailAddress=info@diginotar.nl
-+        {(byte)0x41, (byte)0x0f, (byte)0x36, (byte)0x36, (byte)0x32, (byte)0x58, (byte)0xf3, (byte)0x0b, (byte)0x34, (byte)0x7d,
-+         (byte)0x12, (byte)0xce, (byte)0x48, (byte)0x63, (byte)0xe4, (byte)0x33, (byte)0x43, (byte)0x78, (byte)0x06, (byte)0xa8},
-+        // Subject: CN=DigiNotar Cyber CA
-+        // Issuer: CN=GTE CyberTrust Global Root
-+        {(byte)0xba, (byte)0x3e, (byte)0x7b, (byte)0xd3, (byte)0x8c, (byte)0xd7, (byte)0xe1, (byte)0xe6, (byte)0xb9, (byte)0xcd,
-+         (byte)0x4c, (byte)0x21, (byte)0x99, (byte)0x62, (byte)0xe5, (byte)0x9d, (byte)0x7a, (byte)0x2f, (byte)0x4e, (byte)0x37},
-+        // Subject: CN=DigiNotar Services 1024 CA
-+        // Issuer: CN=Entrust.net
-+        {(byte)0xe2, (byte)0x3b, (byte)0x8d, (byte)0x10, (byte)0x5f, (byte)0x87, (byte)0x71, (byte)0x0a, (byte)0x68, (byte)0xd9,
-+         (byte)0x24, (byte)0x80, (byte)0x50, (byte)0xeb, (byte)0xef, (byte)0xc6, (byte)0x27, (byte)0xbe, (byte)0x4c, (byte)0xa6},
-+        // Subject: CN=DigiNotar PKIoverheid CA Organisatie - G2
-+        // Issuer: CN=Staat der Nederlanden Organisatie CA - G2
-+        {(byte)0x7b, (byte)0x2e, (byte)0x16, (byte)0xbc, (byte)0x39, (byte)0xbc, (byte)0xd7, (byte)0x2b, (byte)0x45, (byte)0x6e,
-+         (byte)0x9f, (byte)0x05, (byte)0x5d, (byte)0x1d, (byte)0xe6, (byte)0x15, (byte)0xb7, (byte)0x49, (byte)0x45, (byte)0xdb},
-+        // Subject: CN=DigiNotar PKIoverheid CA Overheid en Bedrijven
-+        // Issuer: CN=Staat der Nederlanden Overheid CA
-+        {(byte)0xe8, (byte)0xf9, (byte)0x12, (byte)0x00, (byte)0xc6, (byte)0x5c, (byte)0xee, (byte)0x16, (byte)0xe0, (byte)0x39,
-+         (byte)0xb9, (byte)0xf8, (byte)0x83, (byte)0x84, (byte)0x16, (byte)0x61, (byte)0x63, (byte)0x5f, (byte)0x81, (byte)0xc5},
-+
-+        // From http://src.chromium.org/viewvc/chrome?view=rev&revision=108479
-+        // Subject: O=Digicert Sdn. Bhd.
-+        // Issuer: CN=GTE CyberTrust Global Root
-+        {(byte)0x01, (byte)0x29, (byte)0xbc, (byte)0xd5, (byte)0xb4, (byte)0x48, (byte)0xae, (byte)0x8d, (byte)0x24, (byte)0x96,
-+         (byte)0xd1, (byte)0xc3, (byte)0xe1, (byte)0x97, (byte)0x23, (byte)0x91, (byte)0x90, (byte)0x88, (byte)0xe1, (byte)0x52},
-+    };
-+
-+    private static boolean isPublicKeyBlackListed(PublicKey publicKey) {
-+        byte[] encoded = publicKey.getEncoded();
-+        Digest digest = new OpenSSLDigest.SHA1();
-+        digest.update(encoded, 0, encoded.length);
-+        byte[] out = new byte[digest.getDigestSize()];
-+        digest.doFinal(out, 0);
-+
-+        for (byte[] sha1 : PUBLIC_KEY_SHA1_BLACKLIST) {
-+            if (Arrays.equals(out, sha1)) {
-+                return true;
-+            }
-+        }
-+        return false;
-+    }
-+
++    private final static CertBlacklist blacklist = new CertBlacklist();
 +    // END android-added
  
      public CertPathValidatorResult engineValidate(
              CertPath certPath,
-@@ -75,6 +146,22 @@
+@@ -75,6 +82,22 @@
          {
              throw new CertPathValidatorException("Certification path is empty.", null, certPath, 0);
          }
@@ -8856,7 +8960,7 @@
 +
 +            if (cert != null) {
 +                BigInteger serial = cert.getSerialNumber();
-+                if (serial != null && SERIAL_BLACKLIST.contains(serial)) {
++                if (blacklist.isSerialNumberBlackListed(serial)) {
 +                    // emulate CRL exception message in RFC3280CertPathUtilities.checkCRLs
 +                    String message = "Certificate revocation of serial 0x" + serial.toString(16);
 +                    System.out.println(message);
@@ -8869,12 +8973,12 @@
  
          //
          // (b)
-@@ -251,6 +338,15 @@
+@@ -251,6 +274,15 @@
  
          for (index = certs.size() - 1; index >= 0; index--)
          {
 +            // BEGIN android-added
-+            if (isPublicKeyBlackListed(workingPublicKey)) {
++            if (blacklist.isPublicKeyBlackListed(workingPublicKey)) {
 +                // emulate CRL exception message in RFC3280CertPathUtilities.checkCRLs
 +                String message = "Certificate revocation of public key " + workingPublicKey;
 +                System.out.println(message);
@@ -8887,7 +8991,7 @@
              //
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java bcprov-jdk16-146/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java	2012-05-11 05:31:26.630725775 +0000
 @@ -1533,7 +1533,9 @@
          for (Enumeration e = permitted.getObjects(); e.hasMoreElements();)
          {
@@ -8901,7 +9005,7 @@
                  subtreesMap.put(tagNo, new HashSet());
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/WrapCipherSpi.java bcprov-jdk16-146/org/bouncycastle/jce/provider/WrapCipherSpi.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/WrapCipherSpi.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/WrapCipherSpi.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/WrapCipherSpi.java	2012-05-11 05:31:26.630725775 +0000
 @@ -22,8 +22,10 @@
  import javax.crypto.ShortBufferException;
  import javax.crypto.spec.IvParameterSpec;
@@ -9033,7 +9137,7 @@
  }
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/X509CertificateObject.java bcprov-jdk16-146/org/bouncycastle/jce/provider/X509CertificateObject.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/X509CertificateObject.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/X509CertificateObject.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/X509CertificateObject.java	2012-05-11 05:31:26.630725775 +0000
 @@ -520,12 +520,20 @@
          return JDKKeyFactory.createPublicKeyFromPublicKeyInfo(c.getSubjectPublicKeyInfo());
      }
@@ -9067,7 +9171,7 @@
              signature = Signature.getInstance(sigName, BouncyCastleProvider.PROVIDER_NAME);
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/X509SignatureUtil.java bcprov-jdk16-146/org/bouncycastle/jce/provider/X509SignatureUtil.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/X509SignatureUtil.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/X509SignatureUtil.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/X509SignatureUtil.java	2012-05-11 05:31:26.630725775 +0000
 @@ -25,7 +25,9 @@
  
  class X509SignatureUtil
@@ -9160,7 +9264,7 @@
              return digestAlgOID.getId();            
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/asymmetric/EC.java bcprov-jdk16-146/org/bouncycastle/jce/provider/asymmetric/EC.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/asymmetric/EC.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/asymmetric/EC.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/asymmetric/EC.java	2012-05-11 05:31:26.630725775 +0000
 @@ -4,8 +4,10 @@
  
  import org.bouncycastle.asn1.DERObjectIdentifier;
@@ -9292,7 +9396,7 @@
          private void addSignatureAlgorithm(
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/asymmetric/ec/ECUtil.java bcprov-jdk16-146/org/bouncycastle/jce/provider/asymmetric/ec/ECUtil.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/asymmetric/ec/ECUtil.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/asymmetric/ec/ECUtil.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/asymmetric/ec/ECUtil.java	2012-05-11 05:31:26.630725775 +0000
 @@ -1,10 +1,14 @@
  package org.bouncycastle.jce.provider.asymmetric.ec;
  
@@ -9379,7 +9483,7 @@
          return name;
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/asymmetric/ec/KeyAgreement.java bcprov-jdk16-146/org/bouncycastle/jce/provider/asymmetric/ec/KeyAgreement.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/asymmetric/ec/KeyAgreement.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/asymmetric/ec/KeyAgreement.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/asymmetric/ec/KeyAgreement.java	2012-05-11 05:31:26.630725775 +0000
 @@ -24,20 +24,26 @@
  import org.bouncycastle.crypto.CipherParameters;
  import org.bouncycastle.crypto.DerivationFunction;
@@ -9707,7 +9811,7 @@
  }
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/asymmetric/ec/KeyPairGenerator.java bcprov-jdk16-146/org/bouncycastle/jce/provider/asymmetric/ec/KeyPairGenerator.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/asymmetric/ec/KeyPairGenerator.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/asymmetric/ec/KeyPairGenerator.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/asymmetric/ec/KeyPairGenerator.java	2012-05-11 05:31:26.630725775 +0000
 @@ -10,10 +10,14 @@
  import java.util.Hashtable;
  
@@ -9906,7 +10010,7 @@
 +}
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/asymmetric/ec/Signature.java bcprov-jdk16-146/org/bouncycastle/jce/provider/asymmetric/ec/Signature.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/asymmetric/ec/Signature.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/asymmetric/ec/Signature.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/asymmetric/ec/Signature.java	2012-05-11 05:31:26.630725775 +0000
 @@ -18,15 +18,21 @@
  import org.bouncycastle.crypto.DSA;
  import org.bouncycastle.crypto.Digest;
@@ -10135,7 +10239,7 @@
 +}
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/symmetric/AES.java bcprov-jdk16-146/org/bouncycastle/jce/provider/symmetric/AES.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/symmetric/AES.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/symmetric/AES.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/symmetric/AES.java	2012-05-11 05:31:26.630725775 +0000
 @@ -13,8 +13,10 @@
  import org.bouncycastle.crypto.CipherKeyGenerator;
  import org.bouncycastle.crypto.engines.AESFastEngine;
@@ -10500,7 +10604,7 @@
  }
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/symmetric/ARC4.java bcprov-jdk16-146/org/bouncycastle/jce/provider/symmetric/ARC4.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/symmetric/ARC4.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/symmetric/ARC4.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/symmetric/ARC4.java	2012-05-11 05:31:26.630725775 +0000
 @@ -27,7 +27,9 @@
      {
          public KeyGen()
@@ -10514,7 +10618,7 @@
  
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/symmetric/Blowfish.java bcprov-jdk16-146/org/bouncycastle/jce/provider/symmetric/Blowfish.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/symmetric/Blowfish.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/symmetric/Blowfish.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/symmetric/Blowfish.java	2012-05-11 05:31:26.630725775 +0000
 @@ -57,7 +57,9 @@
          public Mappings()
          {
@@ -10528,7 +10632,7 @@
              put("AlgorithmParameters.BLOWFISH", "org.bouncycastle.jce.provider.symmetric.Blowfish$AlgParams");
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/symmetric/DESede.java bcprov-jdk16-146/org/bouncycastle/jce/provider/symmetric/DESede.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/jce/provider/symmetric/DESede.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/jce/provider/symmetric/DESede.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/jce/provider/symmetric/DESede.java	2012-05-11 05:31:26.630725775 +0000
 @@ -14,11 +14,15 @@
  import org.bouncycastle.crypto.KeyGenerationParameters;
  import org.bouncycastle.crypto.engines.DESedeEngine;
@@ -10694,7 +10798,7 @@
  }
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/openssl/PEMUtilities.java bcprov-jdk16-146/org/bouncycastle/openssl/PEMUtilities.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/openssl/PEMUtilities.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/openssl/PEMUtilities.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/openssl/PEMUtilities.java	2012-05-11 05:31:26.630725775 +0000
 @@ -45,10 +45,12 @@
          PKCS5_SCHEME_2.add(NISTObjectIdentifiers.id_aes192_CBC);
          PKCS5_SCHEME_2.add(NISTObjectIdentifiers.id_aes256_CBC);
@@ -10714,7 +10818,7 @@
      static int getKeySize(String algorithm)
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/x509/X509Util.java bcprov-jdk16-146/org/bouncycastle/x509/X509Util.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/x509/X509Util.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/x509/X509Util.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/x509/X509Util.java	2012-05-11 05:31:26.620725599 +0000
 @@ -44,14 +44,18 @@
      
      static
@@ -10876,7 +10980,7 @@
      
 diff -Naur bcprov-jdk16-146.orig/org/bouncycastle/x509/extension/X509ExtensionUtil.java bcprov-jdk16-146/org/bouncycastle/x509/extension/X509ExtensionUtil.java
 --- bcprov-jdk16-146.orig/org/bouncycastle/x509/extension/X509ExtensionUtil.java	2011-02-23 20:08:56.000000000 +0000
-+++ bcprov-jdk16-146/org/bouncycastle/x509/extension/X509ExtensionUtil.java	2011-11-07 21:36:23.000000000 +0000
++++ bcprov-jdk16-146/org/bouncycastle/x509/extension/X509ExtensionUtil.java	2012-05-11 05:31:26.620725599 +0000
 @@ -62,7 +62,9 @@
              {
                  GeneralName genName = GeneralName.getInstance(it.nextElement());
diff --git a/src/main/java/org/bouncycastle/jce/provider/CertBlacklist.java b/src/main/java/org/bouncycastle/jce/provider/CertBlacklist.java
new file mode 100644
index 0000000..795fa1a
--- /dev/null
+++ b/src/main/java/org/bouncycastle/jce/provider/CertBlacklist.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.bouncycastle.jce.provider;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.PublicKey;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import libcore.io.IoUtils;
+import org.bouncycastle.crypto.Digest;
+import org.bouncycastle.crypto.digests.OpenSSLDigest;
+import org.bouncycastle.util.encoders.Hex;
+
+public class CertBlacklist {
+
+    private static final String ANDROID_DATA = System.getenv("ANDROID_DATA");
+    private static final String BLACKLIST_ROOT = ANDROID_DATA + "/misc/keychain/";
+    public static final String DEFAULT_PUBKEY_BLACKLIST_PATH = BLACKLIST_ROOT + "pubkey_blacklist.txt";
+    public static final String DEFAULT_SERIAL_BLACKLIST_PATH = BLACKLIST_ROOT + "serial_blacklist.txt";
+
+    // public for testing
+    public final Set<BigInteger> serialBlacklist;
+    public final Set<byte[]> pubkeyBlacklist;
+
+    public CertBlacklist() {
+        this(DEFAULT_PUBKEY_BLACKLIST_PATH, DEFAULT_SERIAL_BLACKLIST_PATH);
+    }
+
+    /** Test only interface, not for public use */
+    public CertBlacklist(String pubkeyBlacklistPath, String serialBlacklistPath) {
+        serialBlacklist = readSerialBlackList(serialBlacklistPath);
+        pubkeyBlacklist = readPublicKeyBlackList(pubkeyBlacklistPath);
+    }
+
+    private static boolean isHex(String value) {
+        try {
+            new BigInteger(value, 16);
+            return true;
+        } catch (NumberFormatException e) {
+            System.logW("Could not parse hex value " + value, e);
+            return false;
+        }
+    }
+
+    private static boolean isPubkeyHash(String value) {
+        if (value.length() != 40) {
+            System.logW("Invalid pubkey hash length: " + value.length());
+            return false;
+         }
+         return isHex(value);
+    }
+
+    private static String readBlacklist(String path) {
+        try {
+            return IoUtils.readFileAsString(path);
+        } catch (FileNotFoundException ignored) {
+        } catch (IOException e) {
+            System.logW("Could not read blacklist", e);
+        }
+        return "";
+    }
+
+    private static final Set<BigInteger> readSerialBlackList(String path) {
+
+        // start out with a base set of known bad values
+        Set<BigInteger> bl = new HashSet<BigInteger>(Arrays.asList(
+            // From http://src.chromium.org/viewvc/chrome/trunk/src/net/base/x509_certificate.cc?revision=78748&view=markup
+            // Not a real certificate. For testing only.
+            new BigInteger("077a59bcd53459601ca6907267a6dd1c", 16),
+            new BigInteger("047ecbe9fca55f7bd09eae36e10cae1e", 16),
+            new BigInteger("d8f35f4eb7872b2dab0692e315382fb0", 16),
+            new BigInteger("b0b7133ed096f9b56fae91c874bd3ac0", 16),
+            new BigInteger("9239d5348f40d1695a745470e1f23f43", 16),
+            new BigInteger("e9028b9578e415dc1a710a2b88154447", 16),
+            new BigInteger("d7558fdaf5f1105bb213282b707729a3", 16),
+            new BigInteger("f5c86af36162f13a64f54f6dc9587c06", 16),
+            new BigInteger("392a434f0e07df1f8aa305de34e0c229", 16),
+            new BigInteger("3e75ced46b693021218830ae86a82a71", 16)
+        ));
+
+        // attempt to augment it with values taken from gservices
+        String serialBlacklist = readBlacklist(path);
+        if (!serialBlacklist.equals("")) {
+            for(String value : serialBlacklist.split(",")) {
+                try {
+                    bl.add(new BigInteger(value, 16));
+                } catch (NumberFormatException e) {
+                    System.logW("Tried to blacklist invalid serial number " + value, e);
+                }
+            }
+        }
+
+        // whether that succeeds or fails, send it on its merry way
+        return Collections.unmodifiableSet(bl);
+    }
+
+    private static final Set<byte[]> readPublicKeyBlackList(String path) {
+
+        // start out with a base set of known bad values
+        Set<byte[]> bl = new HashSet<byte[]>(Arrays.asList(
+            // From http://src.chromium.org/viewvc/chrome/branches/782/src/net/base/x509_certificate.cc?r1=98750&r2=98749&pathrev=98750
+            // C=NL, O=DigiNotar, CN=DigiNotar Root CA/emailAddress=info@diginotar.nl
+            "410f36363258f30b347d12ce4863e433437806a8".getBytes(),
+            // Subject: CN=DigiNotar Cyber CA
+            // Issuer: CN=GTE CyberTrust Global Root
+            "ba3e7bd38cd7e1e6b9cd4c219962e59d7a2f4e37".getBytes(),
+            // Subject: CN=DigiNotar Services 1024 CA
+            // Issuer: CN=Entrust.net
+            "e23b8d105f87710a68d9248050ebefc627be4ca6".getBytes(),
+            // Subject: CN=DigiNotar PKIoverheid CA Organisatie - G2
+            // Issuer: CN=Staat der Nederlanden Organisatie CA - G2
+            "7b2e16bc39bcd72b456e9f055d1de615b74945db".getBytes(),
+            // Subject: CN=DigiNotar PKIoverheid CA Overheid en Bedrijven
+            // Issuer: CN=Staat der Nederlanden Overheid CA
+            "e8f91200c65cee16e039b9f883841661635f81c5".getBytes(),
+            // From http://src.chromium.org/viewvc/chrome?view=rev&revision=108479
+            // Subject: O=Digicert Sdn. Bhd.
+            // Issuer: CN=GTE CyberTrust Global Root
+            "0129bcd5b448ae8d2496d1c3e19723919088e152".getBytes()
+        ));
+
+        // attempt to augment it with values taken from gservices
+        String pubkeyBlacklist = readBlacklist(path);
+        if (!pubkeyBlacklist.equals("")) {
+            for (String value : pubkeyBlacklist.split(",")) {
+                if (isPubkeyHash(value)) {
+                    bl.add(Hex.decode(value));
+                } else {
+                    System.logW("Tried to blacklist invalid pubkey " + value);
+                }
+            }
+        }
+
+        return bl;
+    }
+
+    public boolean isPublicKeyBlackListed(PublicKey publicKey) {
+        byte[] encoded = publicKey.getEncoded();
+        Digest digest = new OpenSSLDigest.SHA1();
+        digest.update(encoded, 0, encoded.length);
+        byte[] out = new byte[digest.getDigestSize()];
+        digest.doFinal(out, 0);
+        return pubkeyBlacklist.contains(out);
+    }
+
+    public boolean isSerialNumberBlackListed(BigInteger serial) {
+        return serialBlacklist.contains(serial);
+    }
+
+}
diff --git a/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java b/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java
index ac55ec8..6f59ffc 100644
--- a/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java
+++ b/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java
@@ -27,10 +27,6 @@
 import org.bouncycastle.asn1.DEREncodable;
 import org.bouncycastle.asn1.DERObjectIdentifier;
 import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-// BEGIN android-added
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.digests.OpenSSLDigest;
-// END android-added
 import org.bouncycastle.jce.exception.ExtCertPathValidatorException;
 import org.bouncycastle.x509.ExtendedPKIXParameters;
 
@@ -42,67 +38,7 @@
         extends CertPathValidatorSpi
 {
     // BEGIN android-added
-
-    // From http://src.chromium.org/viewvc/chrome/trunk/src/net/base/x509_certificate.cc?revision=78748&view=markup
-    private static final Set<BigInteger> SERIAL_BLACKLIST = new HashSet<BigInteger>(Arrays.asList(
-        // Not a real certificate. For testing only.
-        new BigInteger(1, new byte[] {(byte)0x07,(byte)0x7a,(byte)0x59,(byte)0xbc,(byte)0xd5,(byte)0x34,(byte)0x59,(byte)0x60,(byte)0x1c,(byte)0xa6,(byte)0x90,(byte)0x72,(byte)0x67,(byte)0xa6,(byte)0xdd,(byte)0x1c}),
-
-        new BigInteger(1, new byte[] {(byte)0x04,(byte)0x7e,(byte)0xcb,(byte)0xe9,(byte)0xfc,(byte)0xa5,(byte)0x5f,(byte)0x7b,(byte)0xd0,(byte)0x9e,(byte)0xae,(byte)0x36,(byte)0xe1,(byte)0x0c,(byte)0xae,(byte)0x1e}),
-        new BigInteger(1, new byte[] {(byte)0xd8,(byte)0xf3,(byte)0x5f,(byte)0x4e,(byte)0xb7,(byte)0x87,(byte)0x2b,(byte)0x2d,(byte)0xab,(byte)0x06,(byte)0x92,(byte)0xe3,(byte)0x15,(byte)0x38,(byte)0x2f,(byte)0xb0}),
-        new BigInteger(1, new byte[] {(byte)0xb0,(byte)0xb7,(byte)0x13,(byte)0x3e,(byte)0xd0,(byte)0x96,(byte)0xf9,(byte)0xb5,(byte)0x6f,(byte)0xae,(byte)0x91,(byte)0xc8,(byte)0x74,(byte)0xbd,(byte)0x3a,(byte)0xc0}),
-        new BigInteger(1, new byte[] {(byte)0x92,(byte)0x39,(byte)0xd5,(byte)0x34,(byte)0x8f,(byte)0x40,(byte)0xd1,(byte)0x69,(byte)0x5a,(byte)0x74,(byte)0x54,(byte)0x70,(byte)0xe1,(byte)0xf2,(byte)0x3f,(byte)0x43}),
-        new BigInteger(1, new byte[] {(byte)0xe9,(byte)0x02,(byte)0x8b,(byte)0x95,(byte)0x78,(byte)0xe4,(byte)0x15,(byte)0xdc,(byte)0x1a,(byte)0x71,(byte)0x0a,(byte)0x2b,(byte)0x88,(byte)0x15,(byte)0x44,(byte)0x47}),
-        new BigInteger(1, new byte[] {(byte)0xd7,(byte)0x55,(byte)0x8f,(byte)0xda,(byte)0xf5,(byte)0xf1,(byte)0x10,(byte)0x5b,(byte)0xb2,(byte)0x13,(byte)0x28,(byte)0x2b,(byte)0x70,(byte)0x77,(byte)0x29,(byte)0xa3}),
-        new BigInteger(1, new byte[] {(byte)0xf5,(byte)0xc8,(byte)0x6a,(byte)0xf3,(byte)0x61,(byte)0x62,(byte)0xf1,(byte)0x3a,(byte)0x64,(byte)0xf5,(byte)0x4f,(byte)0x6d,(byte)0xc9,(byte)0x58,(byte)0x7c,(byte)0x06}),
-        new BigInteger(1, new byte[] {(byte)0x39,(byte)0x2a,(byte)0x43,(byte)0x4f,(byte)0x0e,(byte)0x07,(byte)0xdf,(byte)0x1f,(byte)0x8a,(byte)0xa3,(byte)0x05,(byte)0xde,(byte)0x34,(byte)0xe0,(byte)0xc2,(byte)0x29}),
-        new BigInteger(1, new byte[] {(byte)0x3e,(byte)0x75,(byte)0xce,(byte)0xd4,(byte)0x6b,(byte)0x69,(byte)0x30,(byte)0x21,(byte)0x21,(byte)0x88,(byte)0x30,(byte)0xae,(byte)0x86,(byte)0xa8,(byte)0x2a,(byte)0x71})
-    ));
-
-    private static final byte[][] PUBLIC_KEY_SHA1_BLACKLIST = {
-        // From http://src.chromium.org/viewvc/chrome/branches/782/src/net/base/x509_certificate.cc?r1=98750&r2=98749&pathrev=98750
-        // C=NL, O=DigiNotar, CN=DigiNotar Root CA/emailAddress=info@diginotar.nl
-        {(byte)0x41, (byte)0x0f, (byte)0x36, (byte)0x36, (byte)0x32, (byte)0x58, (byte)0xf3, (byte)0x0b, (byte)0x34, (byte)0x7d,
-         (byte)0x12, (byte)0xce, (byte)0x48, (byte)0x63, (byte)0xe4, (byte)0x33, (byte)0x43, (byte)0x78, (byte)0x06, (byte)0xa8},
-        // Subject: CN=DigiNotar Cyber CA
-        // Issuer: CN=GTE CyberTrust Global Root
-        {(byte)0xba, (byte)0x3e, (byte)0x7b, (byte)0xd3, (byte)0x8c, (byte)0xd7, (byte)0xe1, (byte)0xe6, (byte)0xb9, (byte)0xcd,
-         (byte)0x4c, (byte)0x21, (byte)0x99, (byte)0x62, (byte)0xe5, (byte)0x9d, (byte)0x7a, (byte)0x2f, (byte)0x4e, (byte)0x37},
-        // Subject: CN=DigiNotar Services 1024 CA
-        // Issuer: CN=Entrust.net
-        {(byte)0xe2, (byte)0x3b, (byte)0x8d, (byte)0x10, (byte)0x5f, (byte)0x87, (byte)0x71, (byte)0x0a, (byte)0x68, (byte)0xd9,
-         (byte)0x24, (byte)0x80, (byte)0x50, (byte)0xeb, (byte)0xef, (byte)0xc6, (byte)0x27, (byte)0xbe, (byte)0x4c, (byte)0xa6},
-        // Subject: CN=DigiNotar PKIoverheid CA Organisatie - G2
-        // Issuer: CN=Staat der Nederlanden Organisatie CA - G2
-        {(byte)0x7b, (byte)0x2e, (byte)0x16, (byte)0xbc, (byte)0x39, (byte)0xbc, (byte)0xd7, (byte)0x2b, (byte)0x45, (byte)0x6e,
-         (byte)0x9f, (byte)0x05, (byte)0x5d, (byte)0x1d, (byte)0xe6, (byte)0x15, (byte)0xb7, (byte)0x49, (byte)0x45, (byte)0xdb},
-        // Subject: CN=DigiNotar PKIoverheid CA Overheid en Bedrijven
-        // Issuer: CN=Staat der Nederlanden Overheid CA
-        {(byte)0xe8, (byte)0xf9, (byte)0x12, (byte)0x00, (byte)0xc6, (byte)0x5c, (byte)0xee, (byte)0x16, (byte)0xe0, (byte)0x39,
-         (byte)0xb9, (byte)0xf8, (byte)0x83, (byte)0x84, (byte)0x16, (byte)0x61, (byte)0x63, (byte)0x5f, (byte)0x81, (byte)0xc5},
-
-        // From http://src.chromium.org/viewvc/chrome?view=rev&revision=108479
-        // Subject: O=Digicert Sdn. Bhd.
-        // Issuer: CN=GTE CyberTrust Global Root
-        {(byte)0x01, (byte)0x29, (byte)0xbc, (byte)0xd5, (byte)0xb4, (byte)0x48, (byte)0xae, (byte)0x8d, (byte)0x24, (byte)0x96,
-         (byte)0xd1, (byte)0xc3, (byte)0xe1, (byte)0x97, (byte)0x23, (byte)0x91, (byte)0x90, (byte)0x88, (byte)0xe1, (byte)0x52},
-    };
-
-    private static boolean isPublicKeyBlackListed(PublicKey publicKey) {
-        byte[] encoded = publicKey.getEncoded();
-        Digest digest = new OpenSSLDigest.SHA1();
-        digest.update(encoded, 0, encoded.length);
-        byte[] out = new byte[digest.getDigestSize()];
-        digest.doFinal(out, 0);
-
-        for (byte[] sha1 : PUBLIC_KEY_SHA1_BLACKLIST) {
-            if (Arrays.equals(out, sha1)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
+    private final static CertBlacklist blacklist = new CertBlacklist();
     // END android-added
 
     public CertPathValidatorResult engineValidate(
@@ -152,7 +88,7 @@
 
             if (cert != null) {
                 BigInteger serial = cert.getSerialNumber();
-                if (serial != null && SERIAL_BLACKLIST.contains(serial)) {
+                if (blacklist.isSerialNumberBlackListed(serial)) {
                     // emulate CRL exception message in RFC3280CertPathUtilities.checkCRLs
                     String message = "Certificate revocation of serial 0x" + serial.toString(16);
                     System.out.println(message);
@@ -339,7 +275,7 @@
         for (index = certs.size() - 1; index >= 0; index--)
         {
             // BEGIN android-added
-            if (isPublicKeyBlackListed(workingPublicKey)) {
+            if (blacklist.isPublicKeyBlackListed(workingPublicKey)) {
                 // emulate CRL exception message in RFC3280CertPathUtilities.checkCRLs
                 String message = "Certificate revocation of public key " + workingPublicKey;
                 System.out.println(message);